ARMBaseInstrInfo.cpp revision 1b6f5a29ab62fd3e763983f31200b4cc69fa752b
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMBaseInstrInfo.cpp - ARM Instruction Information ----------------===//
2334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
3334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//                     The LLVM Compiler Infrastructure
4334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
5334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file is distributed under the University of Illinois Open Source
6334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// License. See LICENSE.TXT for details.
7334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
8334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===//
9334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
10334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file contains the Base ARM implementation of the TargetInstrInfo class.
11334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
12334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===//
13334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
14334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMBaseInstrInfo.h"
15334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARM.h"
160e5233a9e5ee9385c6a940e3985194d77bee0bbbCraig Topper#include "ARMBaseRegisterInfo.h"
17d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng#include "ARMConstantPoolValue.h"
1848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng#include "ARMHazardRecognizer.h"
19334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMMachineFunctionInfo.h"
20ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
22334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/LiveVariables.h"
23d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
24334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineFrameInfo.h"
25334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineInstrBuilder.h"
26334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineJumpTableInfo.h"
27249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov#include "llvm/CodeGen/MachineMemOperand.h"
282457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng#include "llvm/CodeGen/MachineRegisterInfo.h"
29ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "llvm/CodeGen/SelectionDAGNodes.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalValue.h"
33af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h"
34f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak#include "llvm/Support/BranchProbability.h"
35334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/Support/CommandLine.h"
36f95215f551949d5e5adfbf4753aa833b9009b77aAnton Korobeynikov#include "llvm/Support/Debug.h"
37c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
3822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
394db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR
4022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "ARMGenInstrInfo.inc"
4122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
42334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinusing namespace llvm;
43334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
44334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic cl::opt<bool>
45334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinEnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
46334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin               cl::desc("Enable ARM 2-addr to 3-addr conv"));
47334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
4861545829832ba0375249c42c84843d0b62c8f55fJakob Stoklund Olesenstatic cl::opt<bool>
493805d85e38c29d9106c758b63851eb847201f315Jakob Stoklund OlesenWidenVMOVS("widen-vmovs", cl::Hidden, cl::init(true),
5061545829832ba0375249c42c84843d0b62c8f55fJakob Stoklund Olesen           cl::desc("Widen ARM vmovs to vmovd when possible"));
5161545829832ba0375249c42c84843d0b62c8f55fJakob Stoklund Olesen
52eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilsonstatic cl::opt<unsigned>
53eb1641d54a7eda7717304bc4d55d059208d8ebedBob WilsonSwiftPartialUpdateClearance("swift-partial-update-clearance",
54eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson     cl::Hidden, cl::init(12),
55eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson     cl::desc("Clearance before partial register updates"));
56eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
5748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng/// ARM_MLxEntry - Record information about MLA / MLS instructions.
5848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Chengstruct ARM_MLxEntry {
59cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  uint16_t MLxOpc;     // MLA / MLS opcode
60cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  uint16_t MulOpc;     // Expanded multiplication opcode
61cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  uint16_t AddSubOpc;  // Expanded add / sub opcode
6248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  bool NegAcc;         // True if the acc is negated before the add / sub.
6348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  bool HasLane;        // True if instruction has an extra "lane" operand.
6448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng};
6548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
6648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Chengstatic const ARM_MLxEntry ARM_MLxTable[] = {
6748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  // MLxOpc,          MulOpc,           AddSubOpc,       NegAcc, HasLane
6848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  // fp scalar ops
6948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAS,       ARM::VMULS,       ARM::VADDS,      false,  false },
7048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSS,       ARM::VMULS,       ARM::VSUBS,      false,  false },
7148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAD,       ARM::VMULD,       ARM::VADDD,      false,  false },
7248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSD,       ARM::VMULD,       ARM::VSUBD,      false,  false },
7348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VNMLAS,      ARM::VNMULS,      ARM::VSUBS,      true,   false },
7448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VNMLSS,      ARM::VMULS,       ARM::VSUBS,      true,   false },
7548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VNMLAD,      ARM::VNMULD,      ARM::VSUBD,      true,   false },
7648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VNMLSD,      ARM::VMULD,       ARM::VSUBD,      true,   false },
7748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
7848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  // fp SIMD ops
7948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAfd,      ARM::VMULfd,      ARM::VADDfd,     false,  false },
8048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSfd,      ARM::VMULfd,      ARM::VSUBfd,     false,  false },
8148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAfq,      ARM::VMULfq,      ARM::VADDfq,     false,  false },
8248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSfq,      ARM::VMULfq,      ARM::VSUBfq,     false,  false },
8348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAslfd,    ARM::VMULslfd,    ARM::VADDfd,     false,  true  },
8448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSslfd,    ARM::VMULslfd,    ARM::VSUBfd,     false,  true  },
8548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLAslfq,    ARM::VMULslfq,    ARM::VADDfq,     false,  true  },
8648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  { ARM::VMLSslfq,    ARM::VMULslfq,    ARM::VSUBfq,     false,  true  },
8748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng};
8848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
89f95215f551949d5e5adfbf4753aa833b9009b77aAnton KorobeynikovARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI)
904db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  : ARMGenInstrInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
91f95215f551949d5e5adfbf4753aa833b9009b77aAnton Korobeynikov    Subtarget(STI) {
9248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  for (unsigned i = 0, e = array_lengthof(ARM_MLxTable); i != e; ++i) {
9348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    if (!MLxEntryMap.insert(std::make_pair(ARM_MLxTable[i].MLxOpc, i)).second)
9448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng      assert(false && "Duplicated entries?");
9548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    MLxHazardOpcodes.insert(ARM_MLxTable[i].AddSubOpc);
9648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    MLxHazardOpcodes.insert(ARM_MLxTable[i].MulOpc);
9748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  }
9848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng}
9948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
1002da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick// Use a ScoreboardHazardRecognizer for prepass ARM scheduling. TargetInstrImpl
1012da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick// currently defaults to no prepass hazard recognizer.
10248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan ChengScheduleHazardRecognizer *ARMBaseInstrInfo::
1032da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickCreateTargetHazardRecognizer(const TargetMachine *TM,
1042da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick                             const ScheduleDAG *DAG) const {
105c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick  if (usePreRAHazardRecognizer()) {
1062da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick    const InstrItineraryData *II = TM->getInstrItineraryData();
1072da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick    return new ScoreboardHazardRecognizer(II, DAG, "pre-RA-sched");
1082da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  }
109a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  return TargetInstrInfo::CreateTargetHazardRecognizer(TM, DAG);
1102da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick}
1112da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick
1122da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickScheduleHazardRecognizer *ARMBaseInstrInfo::
1132da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickCreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
1142da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick                                   const ScheduleDAG *DAG) const {
11548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  if (Subtarget.isThumb2() || Subtarget.hasVFP2())
11657148c166ab232191098492633c924fad9c44ef3Bill Wendling    return (ScheduleHazardRecognizer *)new ARMHazardRecognizer(II, DAG);
117a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
118334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
119334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
120334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinMachineInstr *
121334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
122334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                        MachineBasicBlock::iterator &MBBI,
123334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                        LiveVariables *LV) const {
12478703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng  // FIXME: Thumb2 support.
12578703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng
126334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (!EnableARM3Addr)
127334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return NULL;
128334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
129334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineInstr *MI = MBBI;
130334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineFunction &MF = *MI->getParent()->getParent();
13199405df044f2c584242e711cc9023ec90356da82Bruno Cardoso Lopes  uint64_t TSFlags = MI->getDesc().TSFlags;
132334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  bool isPre = false;
133334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
134334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  default: return NULL;
135334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMII::IndexModePre:
136334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    isPre = true;
137334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    break;
138334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMII::IndexModePost:
139334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    break;
140334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
141334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
142334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Try splitting an indexed load/store to an un-indexed one plus an add/sub
143334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // operation.
144334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
145334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (MemOpc == 0)
146334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return NULL;
147334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
148334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineInstr *UpdateMI = NULL;
149334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineInstr *MemMI = NULL;
150334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
151e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI->getDesc();
152e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned NumOps = MCID.getNumOperands();
1535a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  bool isLoad = !MI->mayStore();
154334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
155334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  const MachineOperand &Base = MI->getOperand(2);
156334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  const MachineOperand &Offset = MI->getOperand(NumOps-3);
157334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned WBReg = WB.getReg();
158334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned BaseReg = Base.getReg();
159334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned OffReg = Offset.getReg();
160334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned OffImm = MI->getOperand(NumOps-2).getImm();
161334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
162334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  switch (AddrMode) {
163bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Unknown indexed op!");
164334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMII::AddrMode2: {
165334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
166334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    unsigned Amt = ARM_AM::getAM2Offset(OffImm);
167334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (OffReg == 0) {
168e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng      if (ARM_AM::getSOImmVal(Amt) == -1)
169334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        // Can't encode it in a so_imm operand. This transformation will
170334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        // add more than 1 instruction. Abandon!
171334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        return NULL;
172334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
17378703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng                         get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
174e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng        .addReg(BaseReg).addImm(Amt)
175334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Pred).addReg(0).addReg(0);
176334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    } else if (Amt != 0) {
177334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
178334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
179334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
18092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                         get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
181334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
182334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Pred).addReg(0).addReg(0);
183334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    } else
184334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
18578703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng                         get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
186334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(BaseReg).addReg(OffReg)
187334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Pred).addReg(0).addReg(0);
188334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    break;
189334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
190334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMII::AddrMode3 : {
191334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
192334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    unsigned Amt = ARM_AM::getAM3Offset(OffImm);
193334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (OffReg == 0)
194334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
195334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
19678703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng                         get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
197334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(BaseReg).addImm(Amt)
198334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Pred).addReg(0).addReg(0);
199334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    else
200334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
20178703ddafe3d037f75d8ca188e4829d238289ac3Evan Cheng                         get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
202334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(BaseReg).addReg(OffReg)
203334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Pred).addReg(0).addReg(0);
204334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    break;
205334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
206334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
207334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
208334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  std::vector<MachineInstr*> NewMIs;
209334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (isPre) {
210334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (isLoad)
211334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      MemMI = BuildMI(MF, MI->getDebugLoc(),
212334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                      get(MemOpc), MI->getOperand(0).getReg())
2133e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach        .addReg(WBReg).addImm(0).addImm(Pred);
214334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    else
215334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      MemMI = BuildMI(MF, MI->getDebugLoc(),
216334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
217334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
218334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    NewMIs.push_back(MemMI);
219334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    NewMIs.push_back(UpdateMI);
220334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  } else {
221334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (isLoad)
222334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      MemMI = BuildMI(MF, MI->getDebugLoc(),
223334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                      get(MemOpc), MI->getOperand(0).getReg())
2243e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach        .addReg(BaseReg).addImm(0).addImm(Pred);
225334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    else
226334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      MemMI = BuildMI(MF, MI->getDebugLoc(),
227334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
228334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
229334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (WB.isDead())
230334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      UpdateMI->getOperand(0).setIsDead();
231334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    NewMIs.push_back(UpdateMI);
232334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    NewMIs.push_back(MemMI);
233334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
234334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
235334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Transfer LiveVariables states, kill / dead info.
236334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (LV) {
237334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
238334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      MachineOperand &MO = MI->getOperand(i);
239c9df025e33ac435adb3b3318d237c36ca7cec659Jakob Stoklund Olesen      if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
240334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        unsigned Reg = MO.getReg();
241334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
242334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
243334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        if (MO.isDef()) {
244334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin          MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
245334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin          if (MO.isDead())
246334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            LV->addVirtualRegisterDead(Reg, NewMI);
247334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        }
248334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        if (MO.isUse() && MO.isKill()) {
249334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin          for (unsigned j = 0; j < 2; ++j) {
250334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            // Look at the two new MI's in reverse order.
251334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            MachineInstr *NewMI = NewMIs[j];
252334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            if (!NewMI->readsRegister(Reg))
253334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin              continue;
254334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            LV->addVirtualRegisterKilled(Reg, NewMI);
255334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            if (VI.removeKill(MI))
256334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin              VI.Kills.push_back(NewMI);
257334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin            break;
258334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin          }
259334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        }
260334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      }
261334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    }
262334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
263334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
264334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MFI->insert(MBBI, NewMIs[1]);
265334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MFI->insert(MBBI, NewMIs[0]);
266334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return NewMIs[0];
267334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
268334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
269334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// Branch analysis.
270334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool
271334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
272334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                MachineBasicBlock *&FBB,
273334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                SmallVectorImpl<MachineOperand> &Cond,
274334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                bool AllowModify) const {
275334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // If the block has no terminators, it just falls into the block after it.
276334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineBasicBlock::iterator I = MBB.end();
27793d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  if (I == MBB.begin())
27893d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    return false;
27993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  --I;
28093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
28193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
28293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return false;
28393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
28493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
285334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
286334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Get the last instruction in the block.
287334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineInstr *LastInst = I;
2880553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng  unsigned LastOpc = LastInst->getOpcode();
2890553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng
2900553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng  // Check if it's an indirect branch first, this should return 'unanalyzable'
2910553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng  // even if it's predicated.
2920553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng  if (isIndirectBranchOpcode(LastOpc))
2930553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng    return true;
2940553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng
2950553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng  if (!isUnpredicatedTerminator(I))
2960553e1efcd3f8ccd8b45302e033924d9f85a5d2fEvan Cheng    return false;
297334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
298334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // If there is only one terminator instruction, process it.
299334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
3005ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng    if (isUncondBranchOpcode(LastOpc)) {
301334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      TBB = LastInst->getOperand(0).getMBB();
302334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      return false;
303334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    }
3045ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng    if (isCondBranchOpcode(LastOpc)) {
305334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      // Block ends with fall-through condbranch.
306334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      TBB = LastInst->getOperand(0).getMBB();
307334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      Cond.push_back(LastInst->getOperand(1));
308334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      Cond.push_back(LastInst->getOperand(2));
309334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      return false;
310334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    }
311334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;  // Can't handle indirect branch.
312334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
313334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
314334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Get the instruction before it if it is a terminator.
315334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineInstr *SecondLastInst = I;
316108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng  unsigned SecondLastOpc = SecondLastInst->getOpcode();
317108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng
318108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng  // If AllowModify is true and the block ends with two or more unconditional
319108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng  // branches, delete all but the first unconditional branch.
320108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng  if (AllowModify && isUncondBranchOpcode(LastOpc)) {
321108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng    while (isUncondBranchOpcode(SecondLastOpc)) {
322108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng      LastInst->eraseFromParent();
323108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng      LastInst = SecondLastInst;
324108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng      LastOpc = LastInst->getOpcode();
325676e258366dd17a0b4ee6ac66914237ce181202eEvan Cheng      if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
326676e258366dd17a0b4ee6ac66914237ce181202eEvan Cheng        // Return now the only terminator is an unconditional branch.
327676e258366dd17a0b4ee6ac66914237ce181202eEvan Cheng        TBB = LastInst->getOperand(0).getMBB();
328676e258366dd17a0b4ee6ac66914237ce181202eEvan Cheng        return false;
329676e258366dd17a0b4ee6ac66914237ce181202eEvan Cheng      } else {
330108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng        SecondLastInst = I;
331108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng        SecondLastOpc = SecondLastInst->getOpcode();
332108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng      }
333108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng    }
334108c8724663354050dc09bb1262c3e4511adf82fEvan Cheng  }
335334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
336334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // If there are three terminators, we don't know what sort of block this is.
337334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
338334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
339334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
3405ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  // If the block ends with a B and a Bcc, handle it.
3415ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
342334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    TBB =  SecondLastInst->getOperand(0).getMBB();
343334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    Cond.push_back(SecondLastInst->getOperand(1));
344334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    Cond.push_back(SecondLastInst->getOperand(2));
345334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    FBB = LastInst->getOperand(0).getMBB();
346334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return false;
347334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
348334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
349334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // If the block ends with two unconditional branches, handle it.  The second
350334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // one is not executed, so remove it.
3515ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
352334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    TBB = SecondLastInst->getOperand(0).getMBB();
353334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    I = LastInst;
354334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (AllowModify)
355334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      I->eraseFromParent();
356334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return false;
357334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
358334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
359334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // ...likewise if it ends with a branch table followed by an unconditional
360334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // branch. The branch folder can create these, and we must get rid of them for
361334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // correctness of Thumb constant islands.
3628d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilson  if ((isJumpTableBranchOpcode(SecondLastOpc) ||
3638d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilson       isIndirectBranchOpcode(SecondLastOpc)) &&
3645ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng      isUncondBranchOpcode(LastOpc)) {
365334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    I = LastInst;
366334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    if (AllowModify)
367334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      I->eraseFromParent();
368334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
369334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
370334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
371334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Otherwise, can't handle this.
372334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return true;
373334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
374334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
375334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
376334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
377334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  MachineBasicBlock::iterator I = MBB.end();
378334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (I == MBB.begin()) return 0;
379334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  --I;
38093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
38193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
38293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return 0;
38393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
38493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
3855ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (!isUncondBranchOpcode(I->getOpcode()) &&
3865ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng      !isCondBranchOpcode(I->getOpcode()))
387334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return 0;
388334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
389334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Remove the branch.
390334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  I->eraseFromParent();
391334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
392334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  I = MBB.end();
393334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
394334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (I == MBB.begin()) return 1;
395334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  --I;
3965ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (!isCondBranchOpcode(I->getOpcode()))
397334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return 1;
398334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
399334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Remove the branch.
400334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  I->eraseFromParent();
401334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return 2;
402334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
403334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
404334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned
405334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
4063bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                               MachineBasicBlock *FBB,
4073bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                               const SmallVectorImpl<MachineOperand> &Cond,
4083bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                               DebugLoc DL) const {
4096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
4106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  int BOpc   = !AFI->isThumbFunction()
4116495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB);
4126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  int BccOpc = !AFI->isThumbFunction()
4136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc);
41451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  bool isThumb = AFI->isThumbFunction() || AFI->isThumb2Function();
415e23dc9c0ef50b0a1934c04c1786f3a0478d62f41Andrew Trick
416334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Shouldn't be a fall through.
417334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
418334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  assert((Cond.size() == 2 || Cond.size() == 0) &&
419334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin         "ARM branch conditions have two components!");
420334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
421334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (FBB == 0) {
422112fb73502d54dd7dd61ae2de24c92d4df181294Owen Anderson    if (Cond.empty()) { // Unconditional branch?
42351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      if (isThumb)
42451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB).addImm(ARMCC::AL).addReg(0);
42551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      else
42651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
427112fb73502d54dd7dd61ae2de24c92d4df181294Owen Anderson    } else
4283bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings      BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
429334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
430334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return 1;
431334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
432334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
433334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Two-way conditional branch.
4343bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings  BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
435334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
43651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  if (isThumb)
43751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB).addImm(ARMCC::AL).addReg(0);
43851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  else
43951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
440334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return 2;
441334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
442334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
443334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo::
444334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
445334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
446334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
447334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return false;
448334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
449334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
450ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Chengbool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
451ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  if (MI->isBundle()) {
452ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    MachineBasicBlock::const_instr_iterator I = MI;
453ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
454ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    while (++I != E && I->isInsideBundle()) {
455ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      int PIdx = I->findFirstPredOperandIdx();
456ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      if (PIdx != -1 && I->getOperand(PIdx).getImm() != ARMCC::AL)
457ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng        return true;
458ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    }
459ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    return false;
460ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  }
461ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
462ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  int PIdx = MI->findFirstPredOperandIdx();
463ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
464ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng}
465ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
466334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo::
467334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinPredicateInstruction(MachineInstr *MI,
468334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                     const SmallVectorImpl<MachineOperand> &Pred) const {
469334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  unsigned Opc = MI->getOpcode();
4705ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (isUncondBranchOpcode(Opc)) {
4715ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng    MI->setDesc(get(getMatchingCondBranchOpcode(Opc)));
472b9efafe54d61e85ca5209c4043aa814f89785195Jakob Stoklund Olesen    MachineInstrBuilder(*MI->getParent()->getParent(), MI)
473b9efafe54d61e85ca5209c4043aa814f89785195Jakob Stoklund Olesen      .addImm(Pred[0].getImm())
474b9efafe54d61e85ca5209c4043aa814f89785195Jakob Stoklund Olesen      .addReg(Pred[1].getReg());
475334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
476334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
477334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
478334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  int PIdx = MI->findFirstPredOperandIdx();
479334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (PIdx != -1) {
480334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    MachineOperand &PMO = MI->getOperand(PIdx);
481334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    PMO.setImm(Pred[0].getImm());
482334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
483334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
484334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
485334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return false;
486334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
487334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
488334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo::
489334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinSubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
490334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                  const SmallVectorImpl<MachineOperand> &Pred2) const {
491334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (Pred1.size() > 2 || Pred2.size() > 2)
492334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return false;
493334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
494334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
495334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
496334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (CC1 == CC2)
497334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
498334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
499334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  switch (CC1) {
500334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  default:
501334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return false;
502334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMCC::AL:
503334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return true;
504334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMCC::HS:
505334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return CC2 == ARMCC::HI;
506334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMCC::LS:
507334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
508334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMCC::GE:
509334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return CC2 == ARMCC::GT;
510334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  case ARMCC::LE:
511334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return CC2 == ARMCC::LT;
512334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
513334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
514334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
515334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
516334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                    std::vector<MachineOperand> &Pred) const {
517334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  bool Found = false;
518334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
519334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    const MachineOperand &MO = MI->getOperand(i);
5202420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen    if ((MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) ||
5212420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen        (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)) {
522334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      Pred.push_back(MO);
523334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin      Found = true;
524334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    }
525334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
526334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
527334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return Found;
528334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
529334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
530ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng/// isPredicable - Return true if the specified instruction can be predicated.
531ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng/// By default, this returns true for every instruction with a
532ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng/// PredicateOperand.
533ac0869dc8a7986855c5557cc67d4709600158ef5Evan Chengbool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const {
5345a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (!MI->isPredicable())
535ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng    return false;
536ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng
5375a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if ((MI->getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) {
538ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng    ARMFunctionInfo *AFI =
539ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng      MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
540d7f0810c934a7d13acb28c42d737ce58ec990ea8Evan Cheng    return AFI->isThumb2Function();
541ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng  }
542ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng  return true;
543ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng}
544334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
54556856b1f46ec1f073ceef4e826c544b8b1691608Chris Lattner/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
54619e57025d458d3cb50804fd821fd89b868a819bdChandler CarruthLLVM_ATTRIBUTE_NOINLINE
547334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
54856856b1f46ec1f073ceef4e826c544b8b1691608Chris Lattner                                unsigned JTI);
549334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
550334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                unsigned JTI) {
55156856b1f46ec1f073ceef4e826c544b8b1691608Chris Lattner  assert(JTI < JT.size());
552334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  return JT[JTI].MBBs.size();
553334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
554334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
555334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// GetInstSize - Return the size of the specified MachineInstr.
556334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin///
557334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
558334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  const MachineBasicBlock &MBB = *MI->getParent();
559334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  const MachineFunction *MF = MBB.getParent();
56033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
561334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
562e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI->getDesc();
56316884415db751c75f2133bd04921393c792b1158Owen Anderson  if (MCID.getSize())
56416884415db751c75f2133bd04921393c792b1158Owen Anderson    return MCID.getSize();
565334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
5664d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  // If this machine instr is an inline asm, measure it.
5674d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (MI->getOpcode() == ARM::INLINEASM)
5684d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI);
5694d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (MI->isLabel())
5704d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 0;
5714d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  unsigned Opc = MI->getOpcode();
5724d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  switch (Opc) {
5734d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::IMPLICIT_DEF:
5744d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::KILL:
5754d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::PROLOG_LABEL:
5764d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::EH_LABEL:
5774d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::DBG_VALUE:
5784d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 0;
5794d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case TargetOpcode::BUNDLE:
5804d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return getInstBundleLength(MI);
5814d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::MOVi16_ga_pcrel:
5824d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::MOVTi16_ga_pcrel:
5834d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2MOVi16_ga_pcrel:
5844d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2MOVTi16_ga_pcrel:
5854d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 4;
5864d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::MOVi32imm:
5874d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2MOVi32imm:
5884d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 8;
5894d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::CONSTPOOL_ENTRY:
5904d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // If this machine instr is a constant pool entry, its size is recorded as
5914d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // operand #2.
5924d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return MI->getOperand(2).getImm();
5934d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::Int_eh_sjlj_longjmp:
5944d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 16;
5954d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::tInt_eh_sjlj_longjmp:
5964d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 10;
5974d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::Int_eh_sjlj_setjmp:
5984d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::Int_eh_sjlj_setjmp_nofp:
5994d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 20;
6004d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::tInt_eh_sjlj_setjmp:
6014d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2Int_eh_sjlj_setjmp:
6024d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2Int_eh_sjlj_setjmp_nofp:
6034d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 12;
6044d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::BR_JTr:
6054d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::BR_JTm:
6064d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::BR_JTadd:
6074d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::tBR_JTr:
6084d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2BR_JT:
6094d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2TBB_JT:
6104d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  case ARM::t2TBH_JT: {
6114d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // These are jumptable branches, i.e. a branch followed by an inlined
6124d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // jumptable. The size is 4 + 4 * number of entries. For TBB, each
6134d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // entry is one byte; TBH two byte each.
6144d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    unsigned EntrySize = (Opc == ARM::t2TBB_JT)
6154d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      ? 1 : ((Opc == ARM::t2TBH_JT) ? 2 : 4);
6164d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    unsigned NumOps = MCID.getNumOperands();
6174d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    MachineOperand JTOP =
6184d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      MI->getOperand(NumOps - (MI->isPredicable() ? 3 : 2));
6194d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    unsigned JTI = JTOP.getIndex();
6204d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
6214d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    assert(MJTI != 0);
6224d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
6234d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    assert(JTI < JT.size());
6244d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
6254d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // 4 aligned. The assembler / linker may add 2 byte padding just before
6264d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // the JT entries.  The size does not include this padding; the
6274d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // constant islands pass does separate bookkeeping for it.
6284d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // FIXME: If we know the size of the function is less than (1 << 16) *2
6294d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // bytes, we can use 16-bit entries instead. Then there won't be an
6304d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // alignment issue.
6314d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
6324d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    unsigned NumEntries = getNumJTEntries(JT, JTI);
6334d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Opc == ARM::t2TBB_JT && (NumEntries & 1))
6344d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      // Make sure the instruction that follows TBB is 2-byte aligned.
6354d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      // FIXME: Constant island pass should insert an "ALIGN" instruction
6364d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      // instead.
6374d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      ++NumEntries;
6384d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return NumEntries * EntrySize + InstSize;
6394d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  }
6404d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default:
6414d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    // Otherwise, pseudo-instruction sizes are zero.
6424d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return 0;
6434d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  }
644334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
645334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
646ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Chengunsigned ARMBaseInstrInfo::getInstBundleLength(const MachineInstr *MI) const {
647ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  unsigned Size = 0;
648ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_instr_iterator I = MI;
649ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
650ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  while (++I != E && I->isInsideBundle()) {
651ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    assert(!I->isBundle() && "No nested bundle!");
652ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    Size += GetInstSizeInBytes(&*I);
653ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  }
654ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  return Size;
655ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng}
656ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
657ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesenvoid ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
658ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                                   MachineBasicBlock::iterator I, DebugLoc DL,
659ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                                   unsigned DestReg, unsigned SrcReg,
660ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                                   bool KillSrc) const {
661ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  bool GPRDest = ARM::GPRRegClass.contains(DestReg);
662ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  bool GPRSrc  = ARM::GPRRegClass.contains(SrcReg);
663ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen
664ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  if (GPRDest && GPRSrc) {
665ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
666ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                                  .addReg(SrcReg, getKillRegState(KillSrc))));
667ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    return;
6687bfdca0206f51132b26094c6f83a5ac97ee0f943David Goodwin  }
669334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
670ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  bool SPRDest = ARM::SPRRegClass.contains(DestReg);
671ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  bool SPRSrc  = ARM::SPRRegClass.contains(SrcReg);
672ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen
673e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier  unsigned Opc = 0;
674142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  if (SPRDest && SPRSrc)
675ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    Opc = ARM::VMOVS;
676142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  else if (GPRDest && SPRSrc)
677ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    Opc = ARM::VMOVRS;
678ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  else if (SPRDest && GPRSrc)
679ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    Opc = ARM::VMOVSR;
680ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  else if (ARM::DPRRegClass.contains(DestReg, SrcReg))
681ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen    Opc = ARM::VMOVD;
682ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  else if (ARM::QPRRegClass.contains(DestReg, SrcReg))
68343967a97cf9a296623e1cf5ed643e2f40b7e5766Owen Anderson    Opc = ARM::VORRq;
684e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier
685e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier  if (Opc) {
686e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg);
68743967a97cf9a296623e1cf5ed643e2f40b7e5766Owen Anderson    MIB.addReg(SrcReg, getKillRegState(KillSrc));
688e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier    if (Opc == ARM::VORRq)
689e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier      MIB.addReg(SrcReg, getKillRegState(KillSrc));
690fea95c6bade86fcfa5bd07efdda9bd902f53be8cChad Rosier    AddDefaultPred(MIB);
691e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier    return;
692e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier  }
693e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier
69485bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  // Handle register classes that require multiple instructions.
69585bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  unsigned BeginIdx = 0;
69685bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  unsigned SubRegs = 0;
6977611a88b58e0a6960cdb5c72dc18a6c93e44cdc2Andrew Trick  int Spacing = 1;
69885bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen
69985bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  // Use VORRq when possible.
70085bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  if (ARM::QQPRRegClass.contains(DestReg, SrcReg))
70185bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VORRq, BeginIdx = ARM::qsub_0, SubRegs = 2;
70285bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::QQQQPRRegClass.contains(DestReg, SrcReg))
70385bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VORRq, BeginIdx = ARM::qsub_0, SubRegs = 4;
70485bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  // Fall back to VMOVD.
70585bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DPairRegClass.contains(DestReg, SrcReg))
70685bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 2;
70785bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DTripleRegClass.contains(DestReg, SrcReg))
70885bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 3;
70985bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DQuadRegClass.contains(DestReg, SrcReg))
71085bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4;
711cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen  else if (ARM::GPRPairRegClass.contains(DestReg, SrcReg))
712cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen    Opc = ARM::MOVr, BeginIdx = ARM::gsub_0, SubRegs = 2;
71385bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen
71485bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DPairSpcRegClass.contains(DestReg, SrcReg))
71585bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 2, Spacing = 2;
71685bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DTripleSpcRegClass.contains(DestReg, SrcReg))
71785bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 3, Spacing = 2;
71885bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen  else if (ARM::DQuadSpcRegClass.contains(DestReg, SrcReg))
71985bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen    Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4, Spacing = 2;
72085bdf2e76a0351468f231f48069c64bc6938f140Jakob Stoklund Olesen
7217611a88b58e0a6960cdb5c72dc18a6c93e44cdc2Andrew Trick  assert(Opc && "Impossible reg-to-reg copy");
722d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick
723d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  const TargetRegisterInfo *TRI = &getRegisterInfo();
724d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  MachineInstrBuilder Mov;
725f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick
726f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick  // Copy register tuples backward when the first Dest reg overlaps with SrcReg.
727f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick  if (TRI->regsOverlap(SrcReg, TRI->getSubReg(DestReg, BeginIdx))) {
728f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick    BeginIdx = BeginIdx + ((SubRegs-1)*Spacing);
729f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick    Spacing = -Spacing;
730f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick  }
731f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick#ifndef NDEBUG
732f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick  SmallSet<unsigned, 4> DstRegs;
733f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick#endif
734d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  for (unsigned i = 0; i != SubRegs; ++i) {
735d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing);
736d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    unsigned Src = TRI->getSubReg(SrcReg,  BeginIdx + i*Spacing);
737d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    assert(Dst && Src && "Bad sub-register");
738f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick#ifndef NDEBUG
739f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick    assert(!DstRegs.count(Src) && "destructive vector copy");
7407611a88b58e0a6960cdb5c72dc18a6c93e44cdc2Andrew Trick    DstRegs.insert(Dst);
741f26e43df26bb7b0c7bf4853477e36611e2c90deaAndrew Trick#endif
742d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst)
743d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick      .addReg(Src);
744d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    // VORR takes two source operands.
745d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    if (Opc == ARM::VORRq)
746d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick      Mov.addReg(Src);
747d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    Mov = AddDefaultPred(Mov);
7481b6f5a29ab62fd3e763983f31200b4cc69fa752bJF Bastien    // MOVr can set CC.
7491b6f5a29ab62fd3e763983f31200b4cc69fa752bJF Bastien    if (Opc == ARM::MOVr)
7501b6f5a29ab62fd3e763983f31200b4cc69fa752bJF Bastien      Mov = AddDefaultCC(Mov);
751e5038e191db82d4d92fdeec1b5bce5cae21f6d8fChad Rosier  }
752d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  // Add implicit super-register defs and kills to the last instruction.
753d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  Mov->addRegisterDefined(DestReg, TRI);
754d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick  if (KillSrc)
755d79dedd458c1de07fbc568ea8c3b4194e94df48eAndrew Trick    Mov->addRegisterKilled(SrcReg, TRI);
756334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
757334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
7584cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northoverconst MachineInstrBuilder &
7594cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim NorthoverARMBaseInstrInfo::AddDReg(MachineInstrBuilder &MIB, unsigned Reg,
7604cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover                          unsigned SubIdx, unsigned State,
7614cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover                          const TargetRegisterInfo *TRI) const {
762c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng  if (!SubIdx)
763c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng    return MIB.addReg(Reg, State);
764c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng
765c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng  if (TargetRegisterInfo::isPhysicalRegister(Reg))
766c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng    return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
767c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng  return MIB.addReg(Reg, State, SubIdx);
768c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng}
769c10b5afbe8138b0fdf3af4ed3e1ddf96cf3cb4cbEvan Cheng
770334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinvoid ARMBaseInstrInfo::
771334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
772334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                    unsigned SrcReg, bool isKill, int FI,
773746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                    const TargetRegisterClass *RC,
774746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                    const TargetRegisterInfo *TRI) const {
775c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
776334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (I != MBB.end()) DL = I->getDebugLoc();
777249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineFunction &MF = *MBB.getParent();
778249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineFrameInfo &MFI = *MF.getFrameInfo();
77931bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach  unsigned Align = MFI.getObjectAlignment(FI);
780249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov
781249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineMemOperand *MMO =
782978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
78359db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOStore,
784249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov                            MFI.getObjectSize(FI),
78531bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach                            Align);
786334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
787e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  switch (RC->getSize()) {
788e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    case 4:
789e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      if (ARM::GPRRegClass.hasSubClassEq(RC)) {
790e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12))
791334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                   .addReg(SrcReg, getKillRegState(isKill))
7927e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
793e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
794e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
795d31c5496d7e1580058b5c6fbc8fd537a641ea590Evan Cheng                   .addReg(SrcReg, getKillRegState(isKill))
796d31c5496d7e1580058b5c6fbc8fd537a641ea590Evan Cheng                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
797e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else
798e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        llvm_unreachable("Unknown reg class!");
799e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      break;
800e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    case 8:
801e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      if (ARM::DPRRegClass.hasSubClassEq(RC)) {
802e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
803334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                   .addReg(SrcReg, getKillRegState(isKill))
804249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
805cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen      } else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
8064cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        if (Subtarget.hasV5TEOps()) {
8074cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::STRD));
8084cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
8094cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
8104cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          MIB.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO);
8114cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover
8124cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          AddDefaultPred(MIB);
8134cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        } else {
8144cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          // Fallback to STM instruction, which has existed since the dawn of
8154cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          // time.
8164cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          MachineInstrBuilder MIB =
8174cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover            AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STMIA))
8184cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover                             .addFrameIndex(FI).addMemOperand(MMO));
8194cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
8204cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover          AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
8214cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        }
822e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else
823e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        llvm_unreachable("Unknown reg class!");
824e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      break;
825e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    case 16:
8265b2f9136644c58ae32e00d8317540692a697d1c9Jakob Stoklund Olesen      if (ARM::DPairRegClass.hasSubClassEq(RC)) {
8277255a4e1332ccb69918ebe041dff05f9e4e5815dJakob Stoklund Olesen        // Use aligned spills if the stack can be realigned.
8287255a4e1332ccb69918ebe041dff05f9e4e5815dJakob Stoklund Olesen        if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
82928f08c93e75d291695ea89b9004145103292e85bJim Grosbach          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64))
830f967ca0eaf30325cabe3c1971bf0dba16cf1b027Bob Wilson                     .addFrameIndex(FI).addImm(16)
83169b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addReg(SrcReg, getKillRegState(isKill))
83269b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addMemOperand(MMO));
833e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        } else {
834e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQIA))
83569b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addReg(SrcReg, getKillRegState(isKill))
83669b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addFrameIndex(FI)
83769b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addMemOperand(MMO));
838e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        }
839e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else
840e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        llvm_unreachable("Unknown reg class!");
841e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      break;
842b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov    case 24:
843b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
844b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        // Use aligned spills if the stack can be realigned.
845b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
846b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1d64TPseudo))
847b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                     .addFrameIndex(FI).addImm(16)
848b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                     .addReg(SrcReg, getKillRegState(isKill))
849b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                     .addMemOperand(MMO));
850b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        } else {
851b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          MachineInstrBuilder MIB =
852b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA))
853b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                       .addFrameIndex(FI))
854b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                       .addMemOperand(MMO);
855b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
856b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
857b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
858b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        }
859b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      } else
860b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        llvm_unreachable("Unknown reg class!");
861b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      break;
862e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    case 32:
863b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
864e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
865e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          // FIXME: It's possible to only store part of the QQ register if the
866e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          // spilled def has a sub-register index.
867e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1d64QPseudo))
868168f382dc67e5940cabdb28dc933c4f91cdd3137Bob Wilson                     .addFrameIndex(FI).addImm(16)
869168f382dc67e5940cabdb28dc933c4f91cdd3137Bob Wilson                     .addReg(SrcReg, getKillRegState(isKill))
870168f382dc67e5940cabdb28dc933c4f91cdd3137Bob Wilson                     .addMemOperand(MMO));
871e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        } else {
872e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          MachineInstrBuilder MIB =
873e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA))
87473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling                       .addFrameIndex(FI))
875e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                       .addMemOperand(MMO);
876e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
877e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
878e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
879e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
880e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        }
881e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else
882e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        llvm_unreachable("Unknown reg class!");
883e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      break;
884e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    case 64:
885e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
886e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MachineInstrBuilder MIB =
887e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA))
888e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                         .addFrameIndex(FI))
889e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                         .addMemOperand(MMO);
890e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
891e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
892e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
893e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
894e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
895e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
896e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
897e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson              AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
898e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else
899e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        llvm_unreachable("Unknown reg class!");
900e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      break;
901e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    default:
902e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
903334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
904334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
905334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
90634327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesenunsigned
90734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund OlesenARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
90834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen                                     int &FrameIndex) const {
90934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  switch (MI->getOpcode()) {
91034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  default: break;
9117e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach  case ARM::STRrs:
91234327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
91334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
91434327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).isReg() &&
91534327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(3).isImm() &&
91634327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).getReg() == 0 &&
91734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(3).getImm() == 0) {
91834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
91934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      return MI->getOperand(0).getReg();
92034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    }
92134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    break;
9227e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach  case ARM::STRi12:
92334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::t2STRi12:
92474472b4bf963c424da04f42dffdb94c85ef964bcJim Grosbach  case ARM::tSTRspi:
92534327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::VSTRD:
92634327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::VSTRS:
92734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
92834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).isImm() &&
92934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).getImm() == 0) {
93034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
93134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      return MI->getOperand(0).getReg();
93234327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    }
93334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    break;
93428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64:
935161474d198d44ab505861c1ec55f022b27314b35Anton Korobeynikov  case ARM::VST1d64TPseudo:
936161474d198d44ab505861c1ec55f022b27314b35Anton Korobeynikov  case ARM::VST1d64QPseudo:
937d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    if (MI->getOperand(0).isFI() &&
938d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen        MI->getOperand(2).getSubReg() == 0) {
939d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      FrameIndex = MI->getOperand(0).getIndex();
940d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      return MI->getOperand(2).getReg();
941d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    }
94231bbc51ac9245bc82c933c9db8358ca9bb558ac5Jakob Stoklund Olesen    break;
94373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMQIA:
944d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
945d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen        MI->getOperand(0).getSubReg() == 0) {
946d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
947d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      return MI->getOperand(0).getReg();
948d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    }
949d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    break;
95034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  }
95134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen
95234327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  return 0;
95334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen}
95434327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen
95536ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesenunsigned ARMBaseInstrInfo::isStoreToStackSlotPostFE(const MachineInstr *MI,
95636ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen                                                    int &FrameIndex) const {
95736ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen  const MachineMemOperand *Dummy;
9585a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  return MI->mayStore() && hasStoreToStackSlot(MI, Dummy, FrameIndex);
95936ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen}
96036ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen
961334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinvoid ARMBaseInstrInfo::
962334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
963334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                     unsigned DestReg, int FI,
964746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                     const TargetRegisterClass *RC,
965746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                     const TargetRegisterInfo *TRI) const {
966c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
967334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  if (I != MBB.end()) DL = I->getDebugLoc();
968249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineFunction &MF = *MBB.getParent();
969249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineFrameInfo &MFI = *MF.getFrameInfo();
97031bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach  unsigned Align = MFI.getObjectAlignment(FI);
971249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov  MachineMemOperand *MMO =
97259db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner    MF.getMachineMemOperand(
973978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad                    MachinePointerInfo::getFixedStack(FI),
97459db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOLoad,
975249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov                            MFI.getObjectSize(FI),
97631bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach                            Align);
977334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
978e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  switch (RC->getSize()) {
979e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  case 4:
980e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    if (ARM::GPRRegClass.hasSubClassEq(RC)) {
981e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg)
9823e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
983e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson
984e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
985e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
986d31c5496d7e1580058b5c6fbc8fd537a641ea590Evan Cheng                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
987e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else
988e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
989ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    break;
990e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  case 8:
991e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    if (ARM::DPRRegClass.hasSubClassEq(RC)) {
992e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
993249fb339ad9d4b921a04de738b9c67d27e328bb7Anton Korobeynikov                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
994cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen    } else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
9954cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover      MachineInstrBuilder MIB;
9964cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover
9974cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover      if (Subtarget.hasV5TEOps()) {
9984cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        MIB = BuildMI(MBB, I, DL, get(ARM::LDRD));
9994cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
10004cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
10014cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        MIB.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO);
10024cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover
10034cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        AddDefaultPred(MIB);
10044cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover      } else {
10054cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        // Fallback to LDM instruction, which has existed since the dawn of
10064cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        // time.
10074cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        MIB = AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDMIA))
10084cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover                                 .addFrameIndex(FI).addMemOperand(MMO));
10094cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        MIB = AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
10104cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover        MIB = AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
10114cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover      }
10124cc1407b84dc6dbbc0d62b1d1b8db7c0ddec86ccTim Northover
1013cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen      if (TargetRegisterInfo::isPhysicalRegister(DestReg))
1014cd275f5687799e63956beabe35fc1718dc022f70Jakob Stoklund Olesen        MIB.addReg(DestReg, RegState::ImplicitDefine);
1015e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else
1016e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
1017ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    break;
1018e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  case 16:
10195b2f9136644c58ae32e00d8317540692a697d1c9Jakob Stoklund Olesen    if (ARM::DPairRegClass.hasSubClassEq(RC)) {
10207255a4e1332ccb69918ebe041dff05f9e4e5815dJakob Stoklund Olesen      if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
102128f08c93e75d291695ea89b9004145103292e85bJim Grosbach        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
1022f967ca0eaf30325cabe3c1971bf0dba16cf1b027Bob Wilson                     .addFrameIndex(FI).addImm(16)
102369b9f9883e10efa266d59a5dd2f4d99de92c6707Evan Cheng                     .addMemOperand(MMO));
1024e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else {
1025e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQIA), DestReg)
1026e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                       .addFrameIndex(FI)
1027e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                       .addMemOperand(MMO));
1028e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      }
1029e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else
1030e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
1031ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    break;
1032b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov  case 24:
1033b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov    if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1034b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
1035b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1d64TPseudo), DestReg)
1036b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                     .addFrameIndex(FI).addImm(16)
1037b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                     .addMemOperand(MMO));
1038b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      } else {
1039b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        MachineInstrBuilder MIB =
1040b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
1041b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                         .addFrameIndex(FI)
1042b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov                         .addMemOperand(MMO));
1043b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead, TRI);
1044b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead, TRI);
1045b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead, TRI);
1046b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov        if (TargetRegisterInfo::isPhysicalRegister(DestReg))
1047b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov          MIB.addReg(DestReg, RegState::ImplicitDefine);
1048b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      }
1049b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov    } else
1050b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov      llvm_unreachable("Unknown reg class!");
1051b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov    break;
1052b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov   case 32:
1053b58d7d03125526c152ade0c75be302b3c9eab997Anton Korobeynikov    if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1054e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
1055e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1d64QPseudo), DestReg)
1056168f382dc67e5940cabdb28dc933c4f91cdd3137Bob Wilson                     .addFrameIndex(FI).addImm(16)
1057168f382dc67e5940cabdb28dc933c4f91cdd3137Bob Wilson                     .addMemOperand(MMO));
1058e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      } else {
1059e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson        MachineInstrBuilder MIB =
106073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
106173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling                       .addFrameIndex(FI))
1062e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                       .addMemOperand(MMO);
1063fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen        MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead, TRI);
1064fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen        MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead, TRI);
1065fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen        MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead, TRI);
1066fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen        MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::DefineNoRead, TRI);
10673247af294996ff8588077c06505b64966ad41542Jakob Stoklund Olesen        if (TargetRegisterInfo::isPhysicalRegister(DestReg))
10683247af294996ff8588077c06505b64966ad41542Jakob Stoklund Olesen          MIB.addReg(DestReg, RegState::ImplicitDefine);
1069e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      }
1070e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else
1071e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
1072ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    break;
1073e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson  case 64:
1074e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1075e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      MachineInstrBuilder MIB =
107673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
107773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling                     .addFrameIndex(FI))
1078e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson                     .addMemOperand(MMO);
1079fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead, TRI);
1080fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead, TRI);
1081fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead, TRI);
1082fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::DefineNoRead, TRI);
1083fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::DefineNoRead, TRI);
1084fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::DefineNoRead, TRI);
1085fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::DefineNoRead, TRI);
1086fce711cb65716f86b4e150f42cbb597bbecf7dbeJakob Stoklund Olesen      MIB = AddDReg(MIB, DestReg, ARM::dsub_7, RegState::DefineNoRead, TRI);
10873247af294996ff8588077c06505b64966ad41542Jakob Stoklund Olesen      if (TargetRegisterInfo::isPhysicalRegister(DestReg))
10883247af294996ff8588077c06505b64966ad41542Jakob Stoklund Olesen        MIB.addReg(DestReg, RegState::ImplicitDefine);
1089e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson    } else
1090e66ef2d5f54391e53d2c0febb1ef854d060716f0Owen Anderson      llvm_unreachable("Unknown reg class!");
1091ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    break;
1092ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson  default:
1093ebe99b2c198ec08c5e4a032ec0afb0345c747706Bob Wilson    llvm_unreachable("Unknown regclass!");
1094334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
1095334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
1096334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
109734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesenunsigned
109834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund OlesenARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
109934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen                                      int &FrameIndex) const {
110034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  switch (MI->getOpcode()) {
110134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  default: break;
11023e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARM::LDRrs:
110334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::t2LDRs:  // FIXME: don't use t2LDRs to access frame.
110434327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
110534327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).isReg() &&
110634327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(3).isImm() &&
110734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).getReg() == 0 &&
110834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(3).getImm() == 0) {
110934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
111034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      return MI->getOperand(0).getReg();
111134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    }
111234327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    break;
11133e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARM::LDRi12:
111434327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::t2LDRi12:
111574472b4bf963c424da04f42dffdb94c85ef964bcJim Grosbach  case ARM::tLDRspi:
111634327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::VLDRD:
111734327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  case ARM::VLDRS:
111834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
111934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).isImm() &&
112034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen        MI->getOperand(2).getImm() == 0) {
112134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
1122d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      return MI->getOperand(0).getReg();
1123d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    }
1124d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    break;
112528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VLD1q64:
1126161474d198d44ab505861c1ec55f022b27314b35Anton Korobeynikov  case ARM::VLD1d64TPseudo:
1127161474d198d44ab505861c1ec55f022b27314b35Anton Korobeynikov  case ARM::VLD1d64QPseudo:
1128d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
1129d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen        MI->getOperand(0).getSubReg() == 0) {
1130d64816a8d04e5b20b7a0628bc1f22607c07e8f69Jakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
113106f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen      return MI->getOperand(0).getReg();
113206f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen    }
113306f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen    break;
113473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMQIA:
113506f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen    if (MI->getOperand(1).isFI() &&
113606f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen        MI->getOperand(0).getSubReg() == 0) {
113706f264e504d75f0426eea55b9f9e36c780d8a4fcJakob Stoklund Olesen      FrameIndex = MI->getOperand(1).getIndex();
113834327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen      return MI->getOperand(0).getReg();
113934327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    }
114034327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen    break;
114134327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  }
114234327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen
114334327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen  return 0;
114434327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen}
114534327856d92d027733524b9418bd188a9e8db5dbJakob Stoklund Olesen
114636ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesenunsigned ARMBaseInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr *MI,
114736ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen                                             int &FrameIndex) const {
114836ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen  const MachineMemOperand *Dummy;
11495a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  return MI->mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex);
115036ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen}
115136ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen
1152142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesenbool ARMBaseInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const{
1153142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // This hook gets to expand COPY instructions before they become
1154142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // copyPhysReg() calls.  Look for VMOVS instructions that can legally be
1155142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // widened to VMOVD.  We prefer the VMOVD when possible because it may be
1156142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // changed into a VORR that can go down the NEON pipeline.
1157bcbf3fddef46f1f6e2f2408064c4b75e4b6c90f5Silviu Baranga  if (!WidenVMOVS || !MI->isCopy() || Subtarget.isCortexA15())
1158142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen    return false;
1159142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen
1160142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // Look for a copy between even S-registers.  That is where we keep floats
1161142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // when using NEON v2f32 instructions for f32 arithmetic.
1162142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  unsigned DstRegS = MI->getOperand(0).getReg();
1163142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  unsigned SrcRegS = MI->getOperand(1).getReg();
1164142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  if (!ARM::SPRRegClass.contains(DstRegS, SrcRegS))
1165142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen    return false;
1166142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen
1167142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  const TargetRegisterInfo *TRI = &getRegisterInfo();
1168142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  unsigned DstRegD = TRI->getMatchingSuperReg(DstRegS, ARM::ssub_0,
1169142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen                                              &ARM::DPRRegClass);
1170142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  unsigned SrcRegD = TRI->getMatchingSuperReg(SrcRegS, ARM::ssub_0,
1171142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen                                              &ARM::DPRRegClass);
1172142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  if (!DstRegD || !SrcRegD)
1173142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen    return false;
1174142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen
1175142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // We want to widen this into a DstRegD = VMOVD SrcRegD copy.  This is only
1176142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // legal if the COPY already defines the full DstRegD, and it isn't a
1177142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  // sub-register insertion.
1178142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  if (!MI->definesRegister(DstRegD, TRI) || MI->readsRegister(DstRegD, TRI))
1179142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen    return false;
1180142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen
11811c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // A dead copy shouldn't show up here, but reject it just in case.
11821c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  if (MI->getOperand(0).isDead())
11831c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen    return false;
11841c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
11851c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // All clear, widen the COPY.
1186142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  DEBUG(dbgs() << "widening:    " << *MI);
118737a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
11881c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
11891c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // Get rid of the old <imp-def> of DstRegD.  Leave it if it defines a Q-reg
11901c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // or some other super-register.
11911c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  int ImpDefIdx = MI->findRegisterDefOperandIdx(DstRegD);
11921c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  if (ImpDefIdx != -1)
11931c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen    MI->RemoveOperand(ImpDefIdx);
11941c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
11951c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // Change the opcode and operands.
1196142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  MI->setDesc(get(ARM::VMOVD));
1197142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  MI->getOperand(0).setReg(DstRegD);
1198142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  MI->getOperand(1).setReg(SrcRegD);
119937a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  AddDefaultPred(MIB);
12001c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
12011c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // We are now reading SrcRegD instead of SrcRegS.  This may upset the
12021c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // register scavenger and machine verifier, so we need to indicate that we
12031c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // are reading an undefined value from SrcRegD, but a proper value from
12041c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // SrcRegS.
12051c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  MI->getOperand(1).setIsUndef();
120637a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  MIB.addReg(SrcRegS, RegState::Implicit);
12071c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
12081c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // SrcRegD may actually contain an unrelated value in the ssub_1
12091c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  // sub-register.  Don't kill it.  Only kill the ssub_0 sub-register.
12101c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  if (MI->getOperand(1).isKill()) {
12111c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen    MI->getOperand(1).setIsKill(false);
12121c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen    MI->addRegisterKilled(SrcRegS, TRI, true);
12131c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen  }
12141c062c24aba08962b4687f56b274f182e5b7a8e5Jakob Stoklund Olesen
1215142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  DEBUG(dbgs() << "replaced by: " << *MI);
1216142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen  return true;
1217142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen}
1218142bd1a54e93f3f66d420717ecba53539a556035Jakob Stoklund Olesen
121930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen/// Create a copy of a const pool value. Update CPI to the new index and return
122030ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen/// the label UID.
122130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesenstatic unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
122230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  MachineConstantPool *MCP = MF.getConstantPool();
122330ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
122430ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
122530ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
122630ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  assert(MCPE.isMachineConstantPoolEntry() &&
122730ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen         "Expecting a machine constantpool entry!");
122830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  ARMConstantPoolValue *ACPV =
122930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
123030ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
12315de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  unsigned PCLabelId = AFI->createPICLabelUId();
123230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  ARMConstantPoolValue *NewCPV = 0;
123351f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  // FIXME: The below assumes PIC relocation model and that the function
123451f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  // is Thumb mode (t1 or t2). PCAdjustment would be 8 for ARM mode PIC, and
123551f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  // zero for non-PIC in ARM or Thumb. The callers are all of thumb LDR
123651f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  // instructions, so that's probably OK, but is PIC always correct when
123751f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  // we get here?
123830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  if (ACPV->isGlobalValue())
12395bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    NewCPV = ARMConstantPoolConstant::
12405bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling      Create(cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
12415bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling             ARMCP::CPValue, 4);
124230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  else if (ACPV->isExtSymbol())
1243fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    NewCPV = ARMConstantPoolSymbol::
1244fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling      Create(MF.getFunction()->getContext(),
1245fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling             cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(), PCLabelId, 4);
124630ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  else if (ACPV->isBlockAddress())
12475bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    NewCPV = ARMConstantPoolConstant::
12485bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling      Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
12495bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling             ARMCP::CPBlockAddress, 4);
125051f5b67395780b8421f4aa6ee998ed51b23dae9dJim Grosbach  else if (ACPV->isLSDA())
12515bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    NewCPV = ARMConstantPoolConstant::Create(MF.getFunction(), PCLabelId,
12525bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling                                             ARMCP::CPLSDA, 4);
1253e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling  else if (ACPV->isMachineBasicBlock())
12543320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling    NewCPV = ARMConstantPoolMBB::
12553320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling      Create(MF.getFunction()->getContext(),
12563320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling             cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
125730ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  else
125830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    llvm_unreachable("Unexpected ARM constantpool value type!!");
125930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
126030ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  return PCLabelId;
126130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen}
126230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
1263fdc834046efd427d474e3b899ec69354c05071e0Evan Chengvoid ARMBaseInstrInfo::
1264fdc834046efd427d474e3b899ec69354c05071e0Evan ChengreMaterialize(MachineBasicBlock &MBB,
1265fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng              MachineBasicBlock::iterator I,
1266fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng              unsigned DestReg, unsigned SubIdx,
1267d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng              const MachineInstr *Orig,
12689edf7deb37f0f97664f279040fa15d89f32e23d9Jakob Stoklund Olesen              const TargetRegisterInfo &TRI) const {
1269fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  unsigned Opcode = Orig->getOpcode();
1270fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  switch (Opcode) {
1271fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  default: {
1272fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
12739edf7deb37f0f97664f279040fa15d89f32e23d9Jakob Stoklund Olesen    MI->substituteRegister(Orig->getOperand(0).getReg(), DestReg, SubIdx, TRI);
1274fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    MBB.insert(I, MI);
1275fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    break;
1276fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  }
1277fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  case ARM::tLDRpci_pic:
1278fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  case ARM::t2LDRpci_pic: {
1279fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    MachineFunction &MF = *MBB.getParent();
1280fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    unsigned CPI = Orig->getOperand(1).getIndex();
128130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    unsigned PCLabelId = duplicateCPV(MF, CPI);
1282fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode),
1283fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng                                      DestReg)
1284fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng      .addConstantPoolIndex(CPI).addImm(PCLabelId);
1285d7d030a44796adc73a6eaa939cd17e52047734c1Chris Lattner    MIB->setMemRefs(Orig->memoperands_begin(), Orig->memoperands_end());
1286fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng    break;
1287fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  }
1288fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  }
1289fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng}
1290fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng
129130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund OlesenMachineInstr *
129230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund OlesenARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
1293a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  MachineInstr *MI = TargetInstrInfo::duplicate(Orig, MF);
129430ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  switch(Orig->getOpcode()) {
129530ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  case ARM::tLDRpci_pic:
129630ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  case ARM::t2LDRpci_pic: {
129730ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    unsigned CPI = Orig->getOperand(1).getIndex();
129830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    unsigned PCLabelId = duplicateCPV(MF, CPI);
129930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    Orig->getOperand(1).setIndex(CPI);
130030ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    Orig->getOperand(2).setImm(PCLabelId);
130130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen    break;
130230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  }
130330ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  }
130430ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  return MI;
130530ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen}
130630ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
1307506049f29f4f202a8e45feb916cc0264440a7f6dEvan Chengbool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
13089fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng                                        const MachineInstr *MI1,
13099fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng                                        const MachineRegisterInfo *MRI) const {
1310d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng  int Opcode = MI0->getOpcode();
1311d7e3cc840b81b0438e47f05d9664137a198876dfEvan Cheng  if (Opcode == ARM::t2LDRpci ||
13129b82425cb0105fd5704f6b9bcd5e7693b05b1759Evan Cheng      Opcode == ARM::t2LDRpci_pic ||
13139b82425cb0105fd5704f6b9bcd5e7693b05b1759Evan Cheng      Opcode == ARM::tLDRpci ||
13149fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      Opcode == ARM::tLDRpci_pic ||
131553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      Opcode == ARM::MOV_ga_dyn ||
131653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      Opcode == ARM::MOV_ga_pcrel ||
131753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      Opcode == ARM::MOV_ga_pcrel_ldr ||
131853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      Opcode == ARM::t2MOV_ga_dyn ||
131953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      Opcode == ARM::t2MOV_ga_pcrel) {
1320d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    if (MI1->getOpcode() != Opcode)
1321d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng      return false;
1322d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    if (MI0->getNumOperands() != MI1->getNumOperands())
1323d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng      return false;
1324d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng
1325d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineOperand &MO0 = MI0->getOperand(1);
1326d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineOperand &MO1 = MI1->getOperand(1);
1327d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    if (MO0.getOffset() != MO1.getOffset())
1328d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng      return false;
1329d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng
133053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (Opcode == ARM::MOV_ga_dyn ||
133153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        Opcode == ARM::MOV_ga_pcrel ||
133253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        Opcode == ARM::MOV_ga_pcrel_ldr ||
133353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        Opcode == ARM::t2MOV_ga_dyn ||
133453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        Opcode == ARM::t2MOV_ga_pcrel)
13359fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      // Ignore the PC labels.
13369fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      return MO0.getGlobal() == MO1.getGlobal();
13379fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng
1338d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineFunction *MF = MI0->getParent()->getParent();
1339d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineConstantPool *MCP = MF->getConstantPool();
1340d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    int CPI0 = MO0.getIndex();
1341d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    int CPI1 = MO1.getIndex();
1342d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineConstantPoolEntry &MCPE0 = MCP->getConstants()[CPI0];
1343d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng    const MachineConstantPoolEntry &MCPE1 = MCP->getConstants()[CPI1];
1344d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    bool isARMCP0 = MCPE0.isMachineConstantPoolEntry();
1345d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    bool isARMCP1 = MCPE1.isMachineConstantPoolEntry();
1346d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    if (isARMCP0 && isARMCP1) {
1347d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng      ARMConstantPoolValue *ACPV0 =
1348d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng        static_cast<ARMConstantPoolValue*>(MCPE0.Val.MachineCPVal);
1349d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng      ARMConstantPoolValue *ACPV1 =
1350d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng        static_cast<ARMConstantPoolValue*>(MCPE1.Val.MachineCPVal);
1351d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng      return ACPV0->hasSameValue(ACPV1);
1352d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    } else if (!isARMCP0 && !isARMCP1) {
1353d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng      return MCPE0.Val.ConstVal == MCPE1.Val.ConstVal;
1354d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    }
1355d700617193f3d11deb83cd56c4ababbc8e0ea19fEvan Cheng    return false;
13569fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng  } else if (Opcode == ARM::PICLDR) {
13579fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    if (MI1->getOpcode() != Opcode)
13589fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      return false;
13599fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    if (MI0->getNumOperands() != MI1->getNumOperands())
13609fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      return false;
13619fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng
13629fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    unsigned Addr0 = MI0->getOperand(1).getReg();
13639fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    unsigned Addr1 = MI1->getOperand(1).getReg();
13649fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    if (Addr0 != Addr1) {
13659fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      if (!MRI ||
13669fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng          !TargetRegisterInfo::isVirtualRegister(Addr0) ||
13679fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng          !TargetRegisterInfo::isVirtualRegister(Addr1))
13689fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng        return false;
13699fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng
13709fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      // This assumes SSA form.
13719fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      MachineInstr *Def0 = MRI->getVRegDef(Addr0);
13729fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      MachineInstr *Def1 = MRI->getVRegDef(Addr1);
13739fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      // Check if the loaded value, e.g. a constantpool of a global address, are
13749fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      // the same.
13759fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      if (!produceSameValue(Def0, Def1, MRI))
13769fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng        return false;
13779fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    }
13789fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng
13799fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    for (unsigned i = 3, e = MI0->getNumOperands(); i != e; ++i) {
13809fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      // %vreg12<def> = PICLDR %vreg11, 0, pred:14, pred:%noreg
13819fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      const MachineOperand &MO0 = MI0->getOperand(i);
13829fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      const MachineOperand &MO1 = MI1->getOperand(i);
13839fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng      if (!MO0.isIdenticalTo(MO1))
13849fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng        return false;
13859fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    }
13869fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng    return true;
1387d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng  }
1388d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng
1389506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng  return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
1390d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng}
1391d457e6e9a5cd975baf4d1f0578382ab8373e6153Evan Cheng
13924b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
13934b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// determine if two loads are loading from the same base address. It should
13944b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// only return true if the base pointers are the same and the only differences
13954b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// between the two addresses is the offset. It also returns the offsets by
13964b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// reference.
13979b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick///
13989b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick/// FIXME: remove this in favor of the MachineInstr interface once pre-RA-sched
13999b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick/// is permanently disabled.
14004b722108e2cf8e77157e0879a23789cd44829933Bill Wendlingbool ARMBaseInstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
14014b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                               int64_t &Offset1,
14024b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                               int64_t &Offset2) const {
14034b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Don't worry about Thumb: just ARM and Thumb2.
14044b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (Subtarget.isThumb1Only()) return false;
14054b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14064b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
14074b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14084b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14094b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  switch (Load1->getMachineOpcode()) {
14104b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  default:
14114b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14123e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARM::LDRi12:
1413c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach  case ARM::LDRBi12:
14144b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRD:
14154b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRH:
14164b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRSB:
14174b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRSH:
14184b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::VLDRD:
14194b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::VLDRS:
14204b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRi8:
14214b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRDi8:
14224b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRSHi8:
14234b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRi12:
14244b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRSHi12:
14254b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    break;
14264b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  }
14274b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14284b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  switch (Load2->getMachineOpcode()) {
14294b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  default:
14304b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14313e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARM::LDRi12:
1432c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach  case ARM::LDRBi12:
14334b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRD:
14344b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRH:
14354b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRSB:
14364b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::LDRSH:
14374b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::VLDRD:
14384b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::VLDRS:
14394b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRi8:
14404b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRSHi8:
14414b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRi12:
14424b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  case ARM::t2LDRSHi12:
14434b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    break;
14444b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  }
14454b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14464b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Check if base addresses and chain operands match.
14474b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (Load1->getOperand(0) != Load2->getOperand(0) ||
14484b722108e2cf8e77157e0879a23789cd44829933Bill Wendling      Load1->getOperand(4) != Load2->getOperand(4))
14494b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14504b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14514b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Index should be Reg0.
14524b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (Load1->getOperand(3) != Load2->getOperand(3))
14534b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14544b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14554b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Determine the offsets.
14564b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (isa<ConstantSDNode>(Load1->getOperand(1)) &&
14574b722108e2cf8e77157e0879a23789cd44829933Bill Wendling      isa<ConstantSDNode>(Load2->getOperand(1))) {
14584b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    Offset1 = cast<ConstantSDNode>(Load1->getOperand(1))->getSExtValue();
14594b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    Offset2 = cast<ConstantSDNode>(Load2->getOperand(1))->getSExtValue();
14604b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return true;
14614b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  }
14624b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14634b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  return false;
14644b722108e2cf8e77157e0879a23789cd44829933Bill Wendling}
14654b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14664b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
14677a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner/// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should
14684b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// be scheduled togther. On some targets if two loads are loading from
14694b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// addresses in the same cache line, it's better if they are scheduled
14704b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// together. This function takes two integers that represent the load offsets
14714b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// from the common base address. It returns true if it decides it's desirable
14724b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// to schedule the two loads together. "NumLoads" is the number of loads that
14734b722108e2cf8e77157e0879a23789cd44829933Bill Wendling/// have already been scheduled after Load1.
14749b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick///
14759b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick/// FIXME: remove this in favor of the MachineInstr interface once pre-RA-sched
14769b5caaa9c452f262a52dd5ac7ebbc722da5a63deAndrew Trick/// is permanently disabled.
14774b722108e2cf8e77157e0879a23789cd44829933Bill Wendlingbool ARMBaseInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
14784b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                               int64_t Offset1, int64_t Offset2,
14794b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                               unsigned NumLoads) const {
14804b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Don't worry about Thumb: just ARM and Thumb2.
14814b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (Subtarget.isThumb1Only()) return false;
14824b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14834b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  assert(Offset2 > Offset1);
14844b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14854b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if ((Offset2 - Offset1) / 8 > 64)
14864b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14874b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14884b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (Load1->getMachineOpcode() != Load2->getMachineOpcode())
14894b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;  // FIXME: overly conservative?
14904b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14914b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  // Four loads in a row should be sufficient.
14924b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  if (NumLoads >= 3)
14934b722108e2cf8e77157e0879a23789cd44829933Bill Wendling    return false;
14944b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
14954b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  return true;
14964b722108e2cf8e77157e0879a23789cd44829933Bill Wendling}
14974b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
149886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengbool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
149986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                            const MachineBasicBlock *MBB,
150086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                            const MachineFunction &MF) const {
150157bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // Debug info is never a scheduling boundary. It's necessary to be explicit
150257bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // due to the special treatment of IT instructions below, otherwise a
150357bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // dbg_value followed by an IT will result in the IT instruction being
150457bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // considered a scheduling hazard, which is wrong. It should be the actual
150557bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // instruction preceding the dbg_value instruction(s), just like it is
150657bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // when debug info is not present.
150757bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  if (MI->isDebugValue())
150857bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach    return false;
150957bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach
151086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // Terminators and labels can't be scheduled around.
15115a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI->isTerminator() || MI->isLabel())
151286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    return true;
151386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
151486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // Treat the start of the IT block as a scheduling boundary, but schedule
151586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // t2IT along with all instructions following it.
151686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // FIXME: This is a big hammer. But the alternative is to add all potential
151786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // true and anti dependencies to IT block instructions as implicit operands
151886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // to the t2IT instruction. The added compile time and complexity does not
151986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // seem worth it.
152086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  MachineBasicBlock::const_iterator I = MI;
152157bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  // Make sure to skip any dbg_value instructions
152257bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  while (++I != MBB->end() && I->isDebugValue())
152357bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach    ;
152457bb3948034436a458f5ef857eb2e831a47e7401Jim Grosbach  if (I != MBB->end() && I->getOpcode() == ARM::t2IT)
152586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    return true;
152686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
152786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // Don't attempt to schedule around any instruction that defines
152886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // a stack-oriented pointer, as it's unlikely to be profitable. This
152986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // saves compile time, because it doesn't require every single
153086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // stack slot reference to depend on the instruction that does the
153186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  // modification.
1532a1aa8db51715bdd21770fbe4f7d7abf2c5d28829Jakob Stoklund Olesen  // Calls don't actually change the stack pointer, even if they have imp-defs.
1533209600bb8830036f981238494ab0188c25364837Jakob Stoklund Olesen  // No ARM calling conventions change the stack pointer. (X86 calling
1534209600bb8830036f981238494ab0188c25364837Jakob Stoklund Olesen  // conventions sometimes do).
1535a1aa8db51715bdd21770fbe4f7d7abf2c5d28829Jakob Stoklund Olesen  if (!MI->isCall() && MI->definesRegister(ARM::SP))
153686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    return true;
153786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
153886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  return false;
153986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng}
154086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
1541f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszakbool ARMBaseInstrInfo::
1542f81b7f6069b27c0a515070dcb392f6828437412fJakub StaszakisProfitableToIfCvt(MachineBasicBlock &MBB,
1543f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                    unsigned NumCycles, unsigned ExtraPredCycles,
1544f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                    const BranchProbability &Probability) const {
15455876db7a66fcc4ec4444a9f3e387c1cdc8baf9e5Cameron Zwarich  if (!NumCycles)
154613151432edace19ee867a93b5c14573df4f75d24Evan Cheng    return false;
15472bbb76909126db5bed6bde84b16d94ab5de4d372Michael J. Spencer
1548b20b85168c0e9819e6545f08281e9b83c82108f0Owen Anderson  // Attempt to estimate the relative costs of predication versus branching.
1549f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  unsigned UnpredCost = Probability.getNumerator() * NumCycles;
1550f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  UnpredCost /= Probability.getDenominator();
1551f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  UnpredCost += 1; // The branch itself
1552f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  UnpredCost += Subtarget.getMispredictionPenalty() / 10;
15532bbb76909126db5bed6bde84b16d94ab5de4d372Michael J. Spencer
1554f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  return (NumCycles + ExtraPredCycles) <= UnpredCost;
155513151432edace19ee867a93b5c14573df4f75d24Evan Cheng}
15562bbb76909126db5bed6bde84b16d94ab5de4d372Michael J. Spencer
155713151432edace19ee867a93b5c14573df4f75d24Evan Chengbool ARMBaseInstrInfo::
15588239daf7c83a65a189c352cce3191cdc3bbfe151Evan ChengisProfitableToIfCvt(MachineBasicBlock &TMBB,
15598239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                    unsigned TCycles, unsigned TExtra,
15608239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                    MachineBasicBlock &FMBB,
15618239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                    unsigned FCycles, unsigned FExtra,
1562f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                    const BranchProbability &Probability) const {
15638239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  if (!TCycles || !FCycles)
1564b20b85168c0e9819e6545f08281e9b83c82108f0Owen Anderson    return false;
15652bbb76909126db5bed6bde84b16d94ab5de4d372Michael J. Spencer
1566b20b85168c0e9819e6545f08281e9b83c82108f0Owen Anderson  // Attempt to estimate the relative costs of predication versus branching.
1567f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  unsigned TUnpredCost = Probability.getNumerator() * TCycles;
1568f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  TUnpredCost /= Probability.getDenominator();
1569e23dc9c0ef50b0a1934c04c1786f3a0478d62f41Andrew Trick
1570f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  uint32_t Comp = Probability.getDenominator() - Probability.getNumerator();
1571f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  unsigned FUnpredCost = Comp * FCycles;
1572f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  FUnpredCost /= Probability.getDenominator();
1573f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak
1574f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  unsigned UnpredCost = TUnpredCost + FUnpredCost;
1575f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  UnpredCost += 1; // The branch itself
1576f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  UnpredCost += Subtarget.getMispredictionPenalty() / 10;
1577f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak
1578f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak  return (TCycles + FCycles + TExtra + FExtra) <= UnpredCost;
157913151432edace19ee867a93b5c14573df4f75d24Evan Cheng}
158013151432edace19ee867a93b5c14573df4f75d24Evan Cheng
1581eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilsonbool
1582eb1641d54a7eda7717304bc4d55d059208d8ebedBob WilsonARMBaseInstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB,
1583eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                                            MachineBasicBlock &FMBB) const {
1584eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // Reduce false anti-dependencies to let Swift's out-of-order execution
1585eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // engine do its thing.
1586eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  return Subtarget.isSwift();
1587eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson}
1588eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
15898fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// getInstrPredicate - If instruction is predicated, returns its predicate
15908fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// condition, otherwise returns AL. It also returns the condition code
15918fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// register by reference.
15925adb66a646e2ec32265263739f5b01c3f50c176aEvan ChengARMCC::CondCodes
15935adb66a646e2ec32265263739f5b01c3f50c176aEvan Chengllvm::getInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
15948fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng  int PIdx = MI->findFirstPredOperandIdx();
15958fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng  if (PIdx == -1) {
15968fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng    PredReg = 0;
15978fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng    return ARMCC::AL;
15988fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng  }
15998fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng
16008fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng  PredReg = MI->getOperand(PIdx+1).getReg();
16018fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng  return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
16028fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng}
16038fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng
16048fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng
16056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengint llvm::getMatchingCondBranchOpcode(int Opc) {
16065ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  if (Opc == ARM::B)
16075ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng    return ARM::Bcc;
16084d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (Opc == ARM::tB)
16095ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng    return ARM::tBcc;
16104d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (Opc == ARM::t2B)
16114d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return ARM::t2Bcc;
16125ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng
16135ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  llvm_unreachable("Unknown unconditional branch opcode!");
16145ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng}
16155ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng
1616c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen/// commuteInstruction - Handle commutable instructions.
1617c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund OlesenMachineInstr *
1618c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund OlesenARMBaseInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
1619c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen  switch (MI->getOpcode()) {
1620c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen  case ARM::MOVCCr:
1621c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen  case ARM::t2MOVCCr: {
1622c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    // MOVCC can be commuted by inverting the condition.
1623c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    unsigned PredReg = 0;
1624c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    ARMCC::CondCodes CC = getInstrPredicate(MI, PredReg);
1625c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    // MOVCC AL can't be inverted. Shouldn't happen.
1626c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    if (CC == ARMCC::AL || PredReg != ARM::CPSR)
1627c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen      return NULL;
1628a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen    MI = TargetInstrInfo::commuteInstruction(MI, NewMI);
1629c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    if (!MI)
1630c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen      return NULL;
1631c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    // After swapping the MOVCC operands, also invert the condition.
1632c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    MI->getOperand(MI->findFirstPredOperandIdx())
1633c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen      .setImm(ARMCC::getOppositeCondition(CC));
1634c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen    return MI;
1635c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen  }
1636c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen  }
1637a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  return TargetInstrInfo::commuteInstruction(MI, NewMI);
1638c5041cac7d3aeaa7350abadf2a7ada92e8da27dcJakob Stoklund Olesen}
16396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
16402860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen/// Identify instructions that can be folded into a MOVCC instruction, and
1641098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen/// return the defining instruction.
1642098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesenstatic MachineInstr *canFoldIntoMOVCC(unsigned Reg,
1643098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen                                      const MachineRegisterInfo &MRI,
1644098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen                                      const TargetInstrInfo *TII) {
16452860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  if (!TargetRegisterInfo::isVirtualRegister(Reg))
16462860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    return 0;
16472860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  if (!MRI.hasOneNonDBGUse(Reg))
16482860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    return 0;
1649098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  MachineInstr *MI = MRI.getVRegDef(Reg);
16502860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  if (!MI)
16512860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    return 0;
1652098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  // MI is folded into the MOVCC by predicating it.
1653098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  if (!MI->isPredicable())
1654098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen    return 0;
16552860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  // Check if MI has any non-dead defs or physreg uses. This also detects
16562860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  // predicated instructions which will be reading CPSR.
16572860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) {
16582860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    const MachineOperand &MO = MI->getOperand(i);
1659a7fb3f68047556a7355e1f1080fb3d1ca9eb7078Jakob Stoklund Olesen    // Reject frame index operands, PEI can't handle the predicated pseudos.
1660a7fb3f68047556a7355e1f1080fb3d1ca9eb7078Jakob Stoklund Olesen    if (MO.isFI() || MO.isCPI() || MO.isJTI())
1661a7fb3f68047556a7355e1f1080fb3d1ca9eb7078Jakob Stoklund Olesen      return 0;
16622860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    if (!MO.isReg())
16632860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen      continue;
1664098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen    // MI can't have any tied operands, that would conflict with predication.
1665098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen    if (MO.isTied())
1666098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen      return 0;
16672860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
16682860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen      return 0;
16692860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen    if (MO.isDef() && !MO.isDead())
16702860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen      return 0;
16712860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen  }
1672098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  bool DontMoveAcrossStores = true;
1673098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  if (!MI->isSafeToMove(TII, /* AliasAnalysis = */ 0, DontMoveAcrossStores))
1674098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen    return 0;
1675098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  return MI;
16762860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen}
16772860b7ea3a1d60213ee7228bd274bc4f8b170772Jakob Stoklund Olesen
1678053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesenbool ARMBaseInstrInfo::analyzeSelect(const MachineInstr *MI,
1679053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen                                     SmallVectorImpl<MachineOperand> &Cond,
1680053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen                                     unsigned &TrueOp, unsigned &FalseOp,
1681053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen                                     bool &Optimizable) const {
1682053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
1683053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen         "Unknown select instruction");
1684053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // MOVCC operands:
1685053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // 0: Def.
1686053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // 1: True use.
1687053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // 2: False use.
1688053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // 3: Condition code.
1689053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // 4: CPSR use.
1690053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  TrueOp = 1;
1691053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  FalseOp = 2;
1692053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  Cond.push_back(MI->getOperand(3));
1693053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  Cond.push_back(MI->getOperand(4));
1694053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // We can always fold a def.
1695053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  Optimizable = true;
1696053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  return false;
1697053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen}
1698053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1699053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund OlesenMachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
1700053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen                                               bool PreferFalse) const {
1701053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
1702053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen         "Unknown select instruction");
1703053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
1704098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  MachineInstr *DefMI = canFoldIntoMOVCC(MI->getOperand(2).getReg(), MRI, this);
1705098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  bool Invert = !DefMI;
1706098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  if (!DefMI)
1707098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen    DefMI = canFoldIntoMOVCC(MI->getOperand(1).getReg(), MRI, this);
1708098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  if (!DefMI)
1709053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen    return 0;
1710053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1711053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // Create a new predicated version of DefMI.
1712053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // Rfalse is the first use.
1713053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
1714098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen                                      DefMI->getDesc(),
1715098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen                                      MI->getOperand(0).getReg());
1716053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1717053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // Copy all the DefMI operands, excluding its (null) predicate.
1718053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  const MCInstrDesc &DefDesc = DefMI->getDesc();
1719053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  for (unsigned i = 1, e = DefDesc.getNumOperands();
1720053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen       i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
1721053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen    NewMI.addOperand(DefMI->getOperand(i));
1722053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1723053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  unsigned CondCode = MI->getOperand(3).getImm();
1724053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  if (Invert)
1725053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen    NewMI.addImm(ARMCC::getOppositeCondition(ARMCC::CondCodes(CondCode)));
1726053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  else
1727053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen    NewMI.addImm(CondCode);
1728053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  NewMI.addOperand(MI->getOperand(4));
1729053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1730053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // DefMI is not the -S version that sets CPSR, so add an optional %noreg.
1731053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  if (NewMI->hasOptionalDef())
1732053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen    AddDefaultCC(NewMI);
1733053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
1734098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  // The output register value when the predicate is false is an implicit
1735098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  // register operand tied to the first def.
1736098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  // The tie makes the register allocator ensure the FalseReg is allocated the
1737098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  // same register as operand 0.
1738098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  MachineOperand FalseReg = MI->getOperand(Invert ? 2 : 1);
1739098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  FalseReg.setImplicit();
1740b9efafe54d61e85ca5209c4043aa814f89785195Jakob Stoklund Olesen  NewMI.addOperand(FalseReg);
1741098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen  NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
1742098c6a547fe540b3bbace4c3d4713f400c67b8a9Jakob Stoklund Olesen
1743053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  // The caller will erase MI, but not DefMI.
1744053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  DefMI->eraseFromParent();
1745053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen  return NewMI;
1746053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen}
1747053b5b0b3c34d4763511b6dcd8e0150f8e9dd083Jakob Stoklund Olesen
17483be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether the
17493be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// instruction is encoded with an 'S' bit is determined by the optional CPSR
17503be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// def operand.
17513be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick///
17523be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// This will go away once we can teach tblgen how to set the optional CPSR def
17533be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// operand itself.
17543be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trickstruct AddSubFlagsOpcodePair {
1755cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  uint16_t PseudoOpc;
1756cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  uint16_t MachineOpc;
17573be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick};
17583be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
1759cd2859eef83708c00330c94f6842499b48d5ed02Craig Topperstatic const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[] = {
17603be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::ADDSri, ARM::ADDri},
17613be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::ADDSrr, ARM::ADDrr},
17623be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::ADDSrsi, ARM::ADDrsi},
17633be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::ADDSrsr, ARM::ADDrsr},
17643be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17653be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::SUBSri, ARM::SUBri},
17663be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::SUBSrr, ARM::SUBrr},
17673be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::SUBSrsi, ARM::SUBrsi},
17683be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::SUBSrsr, ARM::SUBrsr},
17693be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17703be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::RSBSri, ARM::RSBri},
17713be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::RSBSrsi, ARM::RSBrsi},
17723be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::RSBSrsr, ARM::RSBrsr},
17733be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17743be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2ADDSri, ARM::t2ADDri},
17753be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2ADDSrr, ARM::t2ADDrr},
17763be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2ADDSrs, ARM::t2ADDrs},
17773be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17783be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2SUBSri, ARM::t2SUBri},
17793be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2SUBSrr, ARM::t2SUBrr},
17803be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2SUBSrs, ARM::t2SUBrs},
17813be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17823be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2RSBSri, ARM::t2RSBri},
17833be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  {ARM::t2RSBSrs, ARM::t2RSBrs},
17843be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick};
17853be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17863be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trickunsigned llvm::convertAddSubFlagsOpcode(unsigned OldOpc) {
1787cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper  for (unsigned i = 0, e = array_lengthof(AddSubFlagsOpcodeMap); i != e; ++i)
1788cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper    if (OldOpc == AddSubFlagsOpcodeMap[i].PseudoOpc)
1789cd2859eef83708c00330c94f6842499b48d5ed02Craig Topper      return AddSubFlagsOpcodeMap[i].MachineOpc;
17903be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  return 0;
17913be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick}
17923be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
17936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengvoid llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
17946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                               MachineBasicBlock::iterator &MBBI, DebugLoc dl,
17956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                               unsigned DestReg, unsigned BaseReg, int NumBytes,
17966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                               ARMCC::CondCodes Pred, unsigned PredReg,
179757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                               const ARMBaseInstrInfo &TII, unsigned MIFlags) {
17986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  bool isSub = NumBytes < 0;
17996495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (isSub) NumBytes = -NumBytes;
18006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  while (NumBytes) {
18026495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
18036495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
18046495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(ThisVal && "Didn't extract field correctly");
18056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // We will handle these bits from offset, clear them.
18076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    NumBytes &= ~ThisVal;
18086495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
18106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18116495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // Build the new ADD / SUB.
18126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
18136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
18146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      .addReg(BaseReg, RegState::Kill).addImm(ThisVal)
181557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
181657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      .setMIFlags(MIFlags);
18176495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    BaseReg = DestReg;
18186495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
18196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
18206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
1821cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Chengbool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
1822cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                                unsigned FrameReg, int &Offset,
1823cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                                const ARMBaseInstrInfo &TII) {
18246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  unsigned Opcode = MI.getOpcode();
1825e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI.getDesc();
18266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
18276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  bool isSub = false;
1828764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach
18296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  // Memory operands in inline assembly always use AddrMode2.
18306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (Opcode == ARM::INLINEASM)
18316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    AddrMode = ARMII::AddrMode2;
1832764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach
18336495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (Opcode == ARM::ADDri) {
18346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    Offset += MI.getOperand(FrameRegIdx+1).getImm();
18356495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    if (Offset == 0) {
18366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      // Turn it into a move.
18376495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.setDesc(TII.get(ARM::MOVr));
18386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
18396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.RemoveOperand(FrameRegIdx+1);
1840cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      Offset = 0;
1841cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      return true;
18426495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    } else if (Offset < 0) {
18436495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      Offset = -Offset;
18446495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      isSub = true;
18456495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.setDesc(TII.get(ARM::SUBri));
18466495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
18476495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // Common case: small offset, fits into instruction.
18496495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    if (ARM_AM::getSOImmVal(Offset) != -1) {
18506495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      // Replace the FrameIndex with sp / fp
18516495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
18526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
1853cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      Offset = 0;
1854cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      return true;
18556495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
18566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // Otherwise, pull as much of the immedidate into this ADDri/SUBri
18586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // as possible.
18596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
18606495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
18616495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18626495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // We will handle these bits from offset, clear them.
18636495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    Offset &= ~ThisImmVal;
18646495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
18656495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // Get the properly encoded SOImmVal field.
18666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
18676495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng           "Bit extraction didn't work?");
18686495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
18696495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else {
18706495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned ImmIdx = 0;
18716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    int InstrOffs = 0;
18726495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned NumBits = 0;
18736495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned Scale = 1;
18746495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    switch (AddrMode) {
18753e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARMII::AddrMode_i12: {
18763e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      ImmIdx = FrameRegIdx + 1;
18773e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      InstrOffs = MI.getOperand(ImmIdx).getImm();
18783e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      NumBits = 12;
18793e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      break;
18803e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    }
18816495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    case ARMII::AddrMode2: {
18826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ImmIdx = FrameRegIdx+2;
18836495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
18846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
18856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        InstrOffs *= -1;
18866495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      NumBits = 12;
18876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      break;
18886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
18896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    case ARMII::AddrMode3: {
18906495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ImmIdx = FrameRegIdx+2;
18916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
18926495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
18936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        InstrOffs *= -1;
18946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      NumBits = 8;
18956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      break;
18966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
1897baf31088f1472f48ea5ae81f0b93636cc44ca444Anton Korobeynikov    case ARMII::AddrMode4:
1898a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach    case ARMII::AddrMode6:
1899cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      // Can't fold any offset even if it's zero.
1900cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      return false;
19016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    case ARMII::AddrMode5: {
19026495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ImmIdx = FrameRegIdx+1;
19036495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
19046495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
19056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        InstrOffs *= -1;
19066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      NumBits = 8;
19076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      Scale = 4;
19086495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      break;
19096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
19106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    default:
19116495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      llvm_unreachable("Unsupported addressing mode!");
19126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
19136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
19146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    Offset += InstrOffs * Scale;
19156495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
19166495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    if (Offset < 0) {
19176495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      Offset = -Offset;
19186495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      isSub = true;
19196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
19206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
19216495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    // Attempt to fold address comp. if opcode has offset bits
19226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    if (NumBits > 0) {
19236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      // Common case: small offset, fits into instruction.
19246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      MachineOperand &ImmOp = MI.getOperand(ImmIdx);
19256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      int ImmedOffset = Offset / Scale;
19266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      unsigned Mask = (1 << NumBits) - 1;
19276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      if ((unsigned)Offset <= Mask * Scale) {
19286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        // Replace the FrameIndex with sp
19296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
193077aee8e22c36257716c2df2f275724765704f20cJim Grosbach        // FIXME: When addrmode2 goes away, this will simplify (like the
193177aee8e22c36257716c2df2f275724765704f20cJim Grosbach        // T2 version), as the LDR.i12 versions don't need the encoding
193277aee8e22c36257716c2df2f275724765704f20cJim Grosbach        // tricks for the offset value.
193377aee8e22c36257716c2df2f275724765704f20cJim Grosbach        if (isSub) {
193477aee8e22c36257716c2df2f275724765704f20cJim Grosbach          if (AddrMode == ARMII::AddrMode_i12)
193577aee8e22c36257716c2df2f275724765704f20cJim Grosbach            ImmedOffset = -ImmedOffset;
193677aee8e22c36257716c2df2f275724765704f20cJim Grosbach          else
193777aee8e22c36257716c2df2f275724765704f20cJim Grosbach            ImmedOffset |= 1 << NumBits;
193877aee8e22c36257716c2df2f275724765704f20cJim Grosbach        }
19396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        ImmOp.ChangeToImmediate(ImmedOffset);
1940cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng        Offset = 0;
1941cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng        return true;
19426495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      }
1943764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach
19446495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
19456495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ImmedOffset = ImmedOffset & Mask;
1946063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach      if (isSub) {
1947063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach        if (AddrMode == ARMII::AddrMode_i12)
1948063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach          ImmedOffset = -ImmedOffset;
1949063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach        else
1950063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach          ImmedOffset |= 1 << NumBits;
1951063efbf569e46776093ddf50099c98fdbb362167Jim Grosbach      }
19526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ImmOp.ChangeToImmediate(ImmedOffset);
19536495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      Offset &= ~(Mask*Scale);
19546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    }
19556495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
19566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
1957cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  Offset = (isSub) ? -Offset : Offset;
1958cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  return Offset == 0;
19596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
1960e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
1961de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// analyzeCompare - For a comparison instruction, return the source registers
1962de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// in SrcReg and SrcReg2 if having two register operands, and the value it
1963de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// compares against in CmpValue. Return true if the comparison instruction
1964de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// can be analyzed.
1965e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendlingbool ARMBaseInstrInfo::
1966de7266c611b37ec050efb53b73166081a98cea13Manman RenanalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, unsigned &SrcReg2,
1967de7266c611b37ec050efb53b73166081a98cea13Manman Ren               int &CmpMask, int &CmpValue) const {
1968e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  switch (MI->getOpcode()) {
1969e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  default: break;
197038ae997e63e3e1bb2c8679e01ea74cf8fd0be893Bill Wendling  case ARM::CMPri:
1971e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  case ARM::t2CMPri:
1972e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    SrcReg = MI->getOperand(0).getReg();
1973de7266c611b37ec050efb53b73166081a98cea13Manman Ren    SrcReg2 = 0;
197404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    CmpMask = ~0;
1975e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    CmpValue = MI->getOperand(1).getImm();
1976e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    return true;
1977247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  case ARM::CMPrr:
1978247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  case ARM::t2CMPrr:
1979247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    SrcReg = MI->getOperand(0).getReg();
1980de7266c611b37ec050efb53b73166081a98cea13Manman Ren    SrcReg2 = MI->getOperand(1).getReg();
1981247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    CmpMask = ~0;
1982247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    CmpValue = 0;
1983247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    return true;
198404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  case ARM::TSTri:
198504ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  case ARM::t2TSTri:
198604ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    SrcReg = MI->getOperand(0).getReg();
1987de7266c611b37ec050efb53b73166081a98cea13Manman Ren    SrcReg2 = 0;
198804ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    CmpMask = MI->getOperand(1).getImm();
198904ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    CmpValue = 0;
199004ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    return true;
199104ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  }
199204ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif
199304ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  return false;
199404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif}
199504ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif
199605642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif/// isSuitableForMask - Identify a suitable 'and' instruction that
199705642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif/// operates on the given source register and applies the same mask
199805642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif/// as a 'tst' instruction. Provide a limited look-through for copies.
199905642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif/// When successful, MI will hold the found instruction.
200005642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greifstatic bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg,
20018ff9bb189ce188452e6cae6ed65cb2745814126cGabor Greif                              int CmpMask, bool CommonUse) {
200205642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif  switch (MI->getOpcode()) {
200304ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    case ARM::ANDri:
200404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    case ARM::t2ANDri:
200505642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      if (CmpMask != MI->getOperand(2).getImm())
20068ff9bb189ce188452e6cae6ed65cb2745814126cGabor Greif        return false;
200705642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
200804ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif        return true;
200904ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif      break;
201005642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif    case ARM::COPY: {
201105642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      // Walk down one instruction which is potentially an 'and'.
201205642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      const MachineInstr &Copy = *MI;
2013f000a7a212590bfd45e23c05bff5e1b683d25dd6Michael J. Spencer      MachineBasicBlock::iterator AND(
2014f000a7a212590bfd45e23c05bff5e1b683d25dd6Michael J. Spencer        llvm::next(MachineBasicBlock::iterator(MI)));
201505642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      if (AND == MI->getParent()->end()) return false;
201605642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      MI = AND;
201705642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif      return isSuitableForMask(MI, Copy.getOperand(0).getReg(),
201805642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif                               CmpMask, true);
201905642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif    }
2020e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  }
2021e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
2022e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  return false;
2023e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling}
2024e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
202576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// getSwappedCondition - assume the flags are set by MI(a,b), return
202676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// the condition code if we modify the instructions such that flags are
202776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// set by MI(b,a).
202876c6ccbd4cee0637c961e32435177ab89e931fedManman Reninline static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC) {
202976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  switch (CC) {
203076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  default: return ARMCC::AL;
203176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::EQ: return ARMCC::EQ;
203276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::NE: return ARMCC::NE;
203376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::HS: return ARMCC::LS;
203476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::LO: return ARMCC::HI;
203576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::HI: return ARMCC::LO;
203676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::LS: return ARMCC::HS;
203776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::GE: return ARMCC::LE;
203876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::LT: return ARMCC::GT;
203976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::GT: return ARMCC::LT;
204076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  case ARMCC::LE: return ARMCC::GE;
204176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  }
204276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren}
204376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren
204476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// isRedundantFlagInstr - check whether the first instruction, whose only
204576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// purpose is to update flags, can be made redundant.
204676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// CMPrr can be made redundant by SUBrr if the operands are the same.
204776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// CMPri can be made redundant by SUBri if the operands are the same.
204876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren/// This function can be extended later on.
204976c6ccbd4cee0637c961e32435177ab89e931fedManman Reninline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,
205076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren                                        unsigned SrcReg2, int ImmValue,
205176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren                                        MachineInstr *OI) {
205276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  if ((CmpI->getOpcode() == ARM::CMPrr ||
205376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren       CmpI->getOpcode() == ARM::t2CMPrr) &&
205476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      (OI->getOpcode() == ARM::SUBrr ||
205576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren       OI->getOpcode() == ARM::t2SUBrr) &&
205676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      ((OI->getOperand(1).getReg() == SrcReg &&
205776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        OI->getOperand(2).getReg() == SrcReg2) ||
205876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren       (OI->getOperand(1).getReg() == SrcReg2 &&
205976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        OI->getOperand(2).getReg() == SrcReg)))
206076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    return true;
206176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren
206276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  if ((CmpI->getOpcode() == ARM::CMPri ||
206376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren       CmpI->getOpcode() == ARM::t2CMPri) &&
206476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      (OI->getOpcode() == ARM::SUBri ||
206576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren       OI->getOpcode() == ARM::t2SUBri) &&
206676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      OI->getOperand(1).getReg() == SrcReg &&
206776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      OI->getOperand(2).getImm() == ImmValue)
206876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    return true;
206976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  return false;
207076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren}
207176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren
2072de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// optimizeCompareInstr - Convert the instruction supplying the argument to the
2073de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// comparison into one that sets the zero bit in the flags register;
2074de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// Remove a redundant Compare instruction if an earlier instruction can set the
2075de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// flags in the same way as Compare.
2076de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// E.g. SUBrr(r1,r2) and CMPrr(r1,r2). We also handle the case where two
2077de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// operands are swapped: SUBrr(r1,r2) and CMPrr(r2,r1), by updating the
2078de7266c611b37ec050efb53b73166081a98cea13Manman Ren/// condition code of instructions which use the flags.
2079e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendlingbool ARMBaseInstrInfo::
2080de7266c611b37ec050efb53b73166081a98cea13Manman RenoptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
2081de7266c611b37ec050efb53b73166081a98cea13Manman Ren                     int CmpMask, int CmpValue,
2082de7266c611b37ec050efb53b73166081a98cea13Manman Ren                     const MachineRegisterInfo *MRI) const {
208376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  // Get the unique definition of SrcReg.
208476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
208576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  if (!MI) return false;
208692ad57f066e9f256e4e3d72febf152e68caa80c7Bill Wendling
208704ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  // Masked compares sometimes use the same register as the corresponding 'and'.
208804ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  if (CmpMask != ~0) {
2089519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen    if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(MI)) {
209004ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif      MI = 0;
2091b41ee96d76ccf1eec2fd898def4cfd7c16868708Bill Wendling      for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg),
2092b41ee96d76ccf1eec2fd898def4cfd7c16868708Bill Wendling           UE = MRI->use_end(); UI != UE; ++UI) {
209304ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif        if (UI->getParent() != CmpInstr->getParent()) continue;
209405642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif        MachineInstr *PotentialAND = &*UI;
2095519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen        if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
2096519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen            isPredicated(PotentialAND))
209704ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif          continue;
209805642a3eba3f35aa8fdf6aa16d87561560e60af3Gabor Greif        MI = PotentialAND;
209904ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif        break;
210004ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif      }
210104ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif      if (!MI) return false;
210204ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif    }
210304ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif  }
210404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif
2105247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // Get ready to iterate backward from CmpInstr.
2106247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  MachineBasicBlock::iterator I = CmpInstr, E = MI,
2107247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren                              B = CmpInstr->getParent()->begin();
21080aa38b9381a5be42abd4f5ca5baa8c2930d148d3Bill Wendling
21090aa38b9381a5be42abd4f5ca5baa8c2930d148d3Bill Wendling  // Early exit if CmpInstr is at the beginning of the BB.
21100aa38b9381a5be42abd4f5ca5baa8c2930d148d3Bill Wendling  if (I == B) return false;
21110aa38b9381a5be42abd4f5ca5baa8c2930d148d3Bill Wendling
2112247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // There are two possible candidates which can be changed to set CPSR:
2113247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // One is MI, the other is a SUB instruction.
2114247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
2115247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
2116247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  MachineInstr *Sub = NULL;
2117de7266c611b37ec050efb53b73166081a98cea13Manman Ren  if (SrcReg2 != 0)
2118247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // MI is not a candidate for CMPrr.
2119247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    MI = NULL;
2120de7266c611b37ec050efb53b73166081a98cea13Manman Ren  else if (MI->getParent() != CmpInstr->getParent() || CmpValue != 0) {
2121247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // Conservatively refuse to convert an instruction which isn't in the same
2122247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // BB as the comparison.
2123247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // For CMPri, we need to check Sub, thus we can't return here.
21244949e98cccb98abb0ba3f67c22be757d446ab108Manman Ren    if (CmpInstr->getOpcode() == ARM::CMPri ||
2125247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren       CmpInstr->getOpcode() == ARM::t2CMPri)
2126247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren      MI = NULL;
2127247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    else
2128247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren      return false;
2129247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  }
2130247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
2131247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // Check that CPSR isn't set between the comparison instruction and the one we
2132247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // want to change. At the same time, search for Sub.
213376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren  const TargetRegisterInfo *TRI = &getRegisterInfo();
2134e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  --I;
2135e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  for (; I != E; --I) {
2136e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    const MachineInstr &Instr = *I;
2137e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
213876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    if (Instr.modifiesRegister(ARM::CPSR, TRI) ||
213976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        Instr.readsRegister(ARM::CPSR, TRI))
214040a5eb18b031fa1a5e9697e21e251e613d441cc5Bill Wendling      // This instruction modifies or uses CPSR after the one we want to
214140a5eb18b031fa1a5e9697e21e251e613d441cc5Bill Wendling      // change. We can't do this transformation.
214276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      return false;
2143247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
214476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    // Check whether CmpInstr can be made redundant by the current instruction.
214576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    if (isRedundantFlagInstr(CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
2146247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren      Sub = &*I;
2147247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren      break;
2148247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    }
2149247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
2150691e64a54ce899409abe7c131d15ed75e3c1fef5Evan Cheng    if (I == B)
2151691e64a54ce899409abe7c131d15ed75e3c1fef5Evan Cheng      // The 'and' is below the comparison instruction.
2152691e64a54ce899409abe7c131d15ed75e3c1fef5Evan Cheng      return false;
2153e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  }
2154e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
2155247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // Return false if no candidates exist.
2156247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  if (!MI && !Sub)
2157247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    return false;
2158247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
2159247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  // The single candidate is called MI.
2160247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren  if (!MI) MI = Sub;
2161247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
2162519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen  // We can't use a predicated instruction - it doesn't always write the flags.
2163519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen  if (isPredicated(MI))
2164519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen    return false;
2165519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen
2166e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  switch (MI->getOpcode()) {
2167e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  default: break;
2168ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::RSBrr:
2169df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::RSBri:
2170ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::RSCrr:
2171df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::RSCri:
2172ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::ADDrr:
217338ae997e63e3e1bb2c8679e01ea74cf8fd0be893Bill Wendling  case ARM::ADDri:
2174ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::ADCrr:
2175df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::ADCri:
2176ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::SUBrr:
217738ae997e63e3e1bb2c8679e01ea74cf8fd0be893Bill Wendling  case ARM::SUBri:
2178ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::SBCrr:
2179df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::SBCri:
2180df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::t2RSBri:
2181ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::t2ADDrr:
218238ae997e63e3e1bb2c8679e01ea74cf8fd0be893Bill Wendling  case ARM::t2ADDri:
2183ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::t2ADCrr:
2184df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::t2ADCri:
2185ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::t2SUBrr:
2186df298c9ea64eb335f63fc075d8ef6306682ffe75Owen Anderson  case ARM::t2SUBri:
2187ca3f6a3925e9a6e91022aa211bdc1b6e3f2ff41fCameron Zwarich  case ARM::t2SBCrr:
2188b485de5d8c3fe0c62c0b07f63f64bd10f6803c17Cameron Zwarich  case ARM::t2SBCri:
2189b485de5d8c3fe0c62c0b07f63f64bd10f6803c17Cameron Zwarich  case ARM::ANDrr:
2190b485de5d8c3fe0c62c0b07f63f64bd10f6803c17Cameron Zwarich  case ARM::ANDri:
2191b485de5d8c3fe0c62c0b07f63f64bd10f6803c17Cameron Zwarich  case ARM::t2ANDrr:
21920cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::t2ANDri:
21930cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::ORRrr:
21940cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::ORRri:
21950cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::t2ORRrr:
21960cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::t2ORRri:
21970cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::EORrr:
21980cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::EORri:
21990cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::t2EORrr:
22000cb11ac32fc09c5db42fb801db242ac9fb51f6b1Cameron Zwarich  case ARM::t2EORri: {
2201247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // Scan forward for the use of CPSR
2202247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // When checking against MI: if it's a conditional code requires
220345ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // checking of V bit, then this is not safe to do.
220445ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // It is safe to remove CmpInstr if CPSR is redefined or killed.
220545ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // If we are done with the basic block, we need to check whether CPSR is
220645ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // live-out.
220776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    SmallVector<std::pair<MachineOperand*, ARMCC::CondCodes>, 4>
220876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        OperandsToUpdate;
22092c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng    bool isSafe = false;
22102c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng    I = CmpInstr;
2211247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    E = CmpInstr->getParent()->end();
22122c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng    while (!isSafe && ++I != E) {
22132c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng      const MachineInstr &Instr = *I;
22142c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng      for (unsigned IO = 0, EO = Instr.getNumOperands();
22152c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng           !isSafe && IO != EO; ++IO) {
22162c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        const MachineOperand &MO = Instr.getOperand(IO);
22172420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen        if (MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) {
22182420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen          isSafe = true;
22192420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen          break;
22202420b558de5d291d8503c1339004e5b5bf99a48aJakob Stoklund Olesen        }
22212c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        if (!MO.isReg() || MO.getReg() != ARM::CPSR)
22222c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng          continue;
22232c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        if (MO.isDef()) {
22242c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng          isSafe = true;
22252c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng          break;
22262c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        }
22272c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        // Condition code is after the operand before CPSR.
22282c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng        ARMCC::CondCodes CC = (ARMCC::CondCodes)Instr.getOperand(IO-1).getImm();
222976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        if (Sub) {
223076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          ARMCC::CondCodes NewCC = getSwappedCondition(CC);
223176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          if (NewCC == ARMCC::AL)
2232247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren            return false;
223376c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based
223476c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          // on CMP needs to be updated to be based on SUB.
223576c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          // Push the condition code operands to OperandsToUpdate.
223676c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          // If it is safe to remove CmpInstr, the condition code of these
223776c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          // operands will be modified.
223876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren          if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
223976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren              Sub->getOperand(2).getReg() == SrcReg)
224076c6ccbd4cee0637c961e32435177ab89e931fedManman Ren            OperandsToUpdate.push_back(std::make_pair(&((*I).getOperand(IO-1)),
224176c6ccbd4cee0637c961e32435177ab89e931fedManman Ren                                                      NewCC));
224276c6ccbd4cee0637c961e32435177ab89e931fedManman Ren        }
2243247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren        else
2244247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          switch (CC) {
2245247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          default:
22469af64303fa887a3d9b75e715787ba587c3f18139Manman Ren            // CPSR can be used multiple times, we should continue.
2247247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren            break;
2248247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::VS:
2249247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::VC:
2250247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::GE:
2251247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::LT:
2252247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::GT:
2253247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          case ARMCC::LE:
2254247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren            return false;
2255247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren          }
22562c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng      }
22572c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng    }
22582c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng
225945ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // If CPSR is not killed nor re-defined, we should check whether it is
226045ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    // live-out. If it is live-out, do not optimize.
226145ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    if (!isSafe) {
226245ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren      MachineBasicBlock *MBB = CmpInstr->getParent();
226345ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren      for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
226445ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren               SE = MBB->succ_end(); SI != SE; ++SI)
226545ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren        if ((*SI)->isLiveIn(ARM::CPSR))
226645ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren          return false;
226745ed19499b8f7025d9acf91cc37fbf6ea63abc4fManman Ren    }
22682c339156289d8398bea09c2bb4b735d00d39bdb3Evan Cheng
22693642e64c114e636548888c72c21ae023ee0121a7Evan Cheng    // Toggle the optional operand to CPSR.
22703642e64c114e636548888c72c21ae023ee0121a7Evan Cheng    MI->getOperand(5).setReg(ARM::CPSR);
22713642e64c114e636548888c72c21ae023ee0121a7Evan Cheng    MI->getOperand(5).setIsDef(true);
2272519daf5d2dd80614ac4e529b199e6f3e595bfc80Jakob Stoklund Olesen    assert(!isPredicated(MI) && "Can't use flags from predicated instruction");
2273e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    CmpInstr->eraseFromParent();
2274247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren
2275247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // Modify the condition code of operands in OperandsToUpdate.
2276247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
2277247c5ab07c1c136f37f5ad8ade9a1ee086ca452eManman Ren    // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
227876c6ccbd4cee0637c961e32435177ab89e931fedManman Ren    for (unsigned i = 0, e = OperandsToUpdate.size(); i < e; i++)
227976c6ccbd4cee0637c961e32435177ab89e931fedManman Ren      OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
2280e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling    return true;
2281e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  }
2282b485de5d8c3fe0c62c0b07f63f64bd10f6803c17Cameron Zwarich  }
2283e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
2284e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  return false;
2285e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling}
22865f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
2287c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Chengbool ARMBaseInstrInfo::FoldImmediate(MachineInstr *UseMI,
2288c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                                     MachineInstr *DefMI, unsigned Reg,
2289c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                                     MachineRegisterInfo *MRI) const {
2290c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  // Fold large immediates into add, sub, or, xor.
2291c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  unsigned DefOpc = DefMI->getOpcode();
2292c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
2293c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    return false;
2294c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  if (!DefMI->getOperand(1).isImm())
2295c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    // Could be t2MOVi32imm <ga:xx>
2296c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    return false;
2297c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng
2298c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  if (!MRI->hasOneNonDBGUse(Reg))
2299c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    return false;
2300c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng
2301e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  const MCInstrDesc &DefMCID = DefMI->getDesc();
2302e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  if (DefMCID.hasOptionalDef()) {
2303e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng    unsigned NumOps = DefMCID.getNumOperands();
2304e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng    const MachineOperand &MO = DefMI->getOperand(NumOps-1);
2305e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng    if (MO.getReg() == ARM::CPSR && !MO.isDead())
2306e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      // If DefMI defines CPSR and it is not dead, it's obviously not safe
2307e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      // to delete DefMI.
2308e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      return false;
2309e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  }
2310e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng
2311e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  const MCInstrDesc &UseMCID = UseMI->getDesc();
2312e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  if (UseMCID.hasOptionalDef()) {
2313e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng    unsigned NumOps = UseMCID.getNumOperands();
2314e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng    if (UseMI->getOperand(NumOps-1).getReg() == ARM::CPSR)
2315e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      // If the instruction sets the flag, do not attempt this optimization
2316e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      // since it may change the semantics of the code.
2317e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng      return false;
2318e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng  }
2319e279f5953e9c3d934248cd4d2f24b6179ad9d2e6Evan Cheng
2320c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  unsigned UseOpc = UseMI->getOpcode();
23215c71c7a13715ed6f5bfdd5497172ddec316b68b0Evan Cheng  unsigned NewUseOpc = 0;
2322c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  uint32_t ImmVal = (uint32_t)DefMI->getOperand(1).getImm();
23235c71c7a13715ed6f5bfdd5497172ddec316b68b0Evan Cheng  uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
2324c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  bool Commute = false;
2325c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  switch (UseOpc) {
2326c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  default: return false;
2327c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::SUBrr:
2328c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::ADDrr:
2329c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::ORRrr:
2330c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::EORrr:
2331c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::t2SUBrr:
2332c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::t2ADDrr:
2333c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::t2ORRrr:
2334c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  case ARM::t2EORrr: {
2335c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    Commute = UseMI->getOperand(2).getReg() != Reg;
2336c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    switch (UseOpc) {
2337c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    default: break;
2338c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::SUBrr: {
2339c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      if (Commute)
2340c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng        return false;
2341c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      ImmVal = -ImmVal;
2342c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      NewUseOpc = ARM::SUBri;
2343c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      // Fallthrough
2344c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    }
2345c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::ADDrr:
2346c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::ORRrr:
2347c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::EORrr: {
2348c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      if (!ARM_AM::isSOImmTwoPartVal(ImmVal))
2349c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng        return false;
2350c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      SOImmValV1 = (uint32_t)ARM_AM::getSOImmTwoPartFirst(ImmVal);
2351c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      SOImmValV2 = (uint32_t)ARM_AM::getSOImmTwoPartSecond(ImmVal);
2352c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      switch (UseOpc) {
2353c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      default: break;
2354c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::ADDrr: NewUseOpc = ARM::ADDri; break;
2355c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::ORRrr: NewUseOpc = ARM::ORRri; break;
2356c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::EORrr: NewUseOpc = ARM::EORri; break;
2357c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      }
2358c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      break;
2359c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    }
2360c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::t2SUBrr: {
2361c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      if (Commute)
2362c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng        return false;
2363c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      ImmVal = -ImmVal;
2364c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      NewUseOpc = ARM::t2SUBri;
2365c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      // Fallthrough
2366c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    }
2367c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::t2ADDrr:
2368c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::t2ORRrr:
2369c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    case ARM::t2EORrr: {
2370c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      if (!ARM_AM::isT2SOImmTwoPartVal(ImmVal))
2371c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng        return false;
2372c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
2373c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
2374c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      switch (UseOpc) {
2375c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      default: break;
2376c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::t2ADDrr: NewUseOpc = ARM::t2ADDri; break;
2377c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri; break;
2378c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      case ARM::t2EORrr: NewUseOpc = ARM::t2EORri; break;
2379c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      }
2380c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng      break;
2381c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    }
2382c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng    }
2383c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  }
2384c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  }
2385c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng
2386c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  unsigned OpIdx = Commute ? 2 : 1;
2387c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  unsigned Reg1 = UseMI->getOperand(OpIdx).getReg();
2388c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  bool isKill = UseMI->getOperand(OpIdx).isKill();
2389c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  unsigned NewReg = MRI->createVirtualRegister(MRI->getRegClass(Reg));
2390c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  AddDefaultCC(AddDefaultPred(BuildMI(*UseMI->getParent(),
2391ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng                                      UseMI, UseMI->getDebugLoc(),
2392c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                                      get(NewUseOpc), NewReg)
2393c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                              .addReg(Reg1, getKillRegState(isKill))
2394c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                              .addImm(SOImmValV1)));
2395c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  UseMI->setDesc(get(NewUseOpc));
2396c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  UseMI->getOperand(1).setReg(NewReg);
2397c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  UseMI->getOperand(1).setIsKill();
2398c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  UseMI->getOperand(2).ChangeToImmediate(SOImmValV2);
2399c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  DefMI->eraseFromParent();
2400c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  return true;
2401c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng}
2402c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng
2403eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilsonstatic unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData,
2404eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                                        const MachineInstr *MI) {
2405eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  switch (MI->getOpcode()) {
2406eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  default: {
2407eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    const MCInstrDesc &Desc = MI->getDesc();
2408eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    int UOps = ItinData->getNumMicroOps(Desc.getSchedClass());
2409eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    assert(UOps >= 0 && "bad # UOps");
2410eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return UOps;
2411eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2412eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2413eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRrs:
2414eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRBrs:
2415eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRrs:
2416eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRBrs: {
2417eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShOpVal = MI->getOperand(3).getImm();
2418eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
2419eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2420eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!isSub &&
2421eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        (ShImm == 0 ||
2422eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2423eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
2424eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 1;
2425eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2426eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2427eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2428eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRH:
2429eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRH: {
2430eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!MI->getOperand(2).getReg())
2431eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 1;
2432eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2433eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShOpVal = MI->getOperand(3).getImm();
2434eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
2435eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2436eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!isSub &&
2437eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        (ShImm == 0 ||
2438eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2439eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
2440eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 1;
2441eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2442eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2443eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2444eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSB:
2445eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSH:
2446eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (ARM_AM::getAM3Op(MI->getOperand(3).getImm()) == ARM_AM::sub) ? 3:2;
2447eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2448eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSB_POST:
2449eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSH_POST: {
2450eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2451eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2452eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rm) ? 4 : 3;
2453eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2454eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2455eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDR_PRE_REG:
2456eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRB_PRE_REG: {
2457eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2458eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2459eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rt == Rm)
2460eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 3;
2461eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShOpVal = MI->getOperand(4).getImm();
2462eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
2463eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2464eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!isSub &&
2465eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        (ShImm == 0 ||
2466eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2467eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
2468eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 2;
2469eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 3;
2470eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2471eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2472eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STR_PRE_REG:
2473eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRB_PRE_REG: {
2474eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShOpVal = MI->getOperand(4).getImm();
2475eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
2476eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2477eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!isSub &&
2478eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        (ShImm == 0 ||
2479eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2480eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
2481eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 2;
2482eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 3;
2483eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2484eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2485eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRH_PRE:
2486eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRH_PRE: {
2487eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2488eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2489eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!Rm)
2490eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 2;
2491eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rt == Rm)
2492eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 3;
2493eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (ARM_AM::getAM3Op(MI->getOperand(4).getImm()) == ARM_AM::sub)
2494eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      ? 3 : 2;
2495eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2496eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2497eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDR_POST_REG:
2498eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRB_POST_REG:
2499eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRH_POST: {
2500eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2501eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2502eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rm) ? 3 : 2;
2503eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2504eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2505eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDR_PRE_IMM:
2506eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRB_PRE_IMM:
2507eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDR_POST_IMM:
2508eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRB_POST_IMM:
2509eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRB_POST_IMM:
2510eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRB_POST_REG:
2511eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRB_PRE_IMM:
2512eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRH_POST:
2513eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STR_POST_IMM:
2514eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STR_POST_REG:
2515eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STR_PRE_IMM:
2516eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2517eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2518eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSB_PRE:
2519eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRSH_PRE: {
2520eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2521eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rm == 0)
2522eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 3;
2523eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2524eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rt == Rm)
2525eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 4;
2526eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShOpVal = MI->getOperand(4).getImm();
2527eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
2528eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2529eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!isSub &&
2530eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        (ShImm == 0 ||
2531eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
2532eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
2533eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 3;
2534eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 4;
2535eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2536eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2537eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRD: {
2538eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2539eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rn = MI->getOperand(2).getReg();
2540eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2541eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rm)
2542eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return (ARM_AM::getAM3Op(MI->getOperand(4).getImm()) == ARM_AM::sub) ?4:3;
2543eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rn) ? 3 : 2;
2544eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2545eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2546eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRD: {
2547eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(3).getReg();
2548eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rm)
2549eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return (ARM_AM::getAM3Op(MI->getOperand(4).getImm()) == ARM_AM::sub) ?4:3;
2550eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2551eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2552eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2553eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRD_POST:
2554eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRD_POST:
2555eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 3;
2556eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2557eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRD_POST:
2558eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRD_POST:
2559eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 4;
2560eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2561eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::LDRD_PRE: {
2562eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2563eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rn = MI->getOperand(3).getReg();
2564eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(4).getReg();
2565eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rm)
2566eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return (ARM_AM::getAM3Op(MI->getOperand(5).getImm()) == ARM_AM::sub) ?5:4;
2567eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rn) ? 4 : 3;
2568eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2569eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2570eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRD_PRE: {
2571eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2572eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rn = MI->getOperand(3).getReg();
2573eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rn) ? 4 : 3;
2574eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2575eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2576eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::STRD_PRE: {
2577eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rm = MI->getOperand(4).getReg();
2578eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Rm)
2579eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return (ARM_AM::getAM3Op(MI->getOperand(5).getImm()) == ARM_AM::sub) ?5:4;
2580eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 3;
2581eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2582eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2583eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRD_PRE:
2584eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 3;
2585eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2586eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDR_POST:
2587eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRB_POST:
2588eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRB_PRE:
2589eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSBi12:
2590eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSBi8:
2591eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSBpci:
2592eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSBs:
2593eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRH_POST:
2594eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRH_PRE:
2595eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSBT:
2596eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSB_POST:
2597eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSB_PRE:
2598eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSH_POST:
2599eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSH_PRE:
2600eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSHi12:
2601eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSHi8:
2602eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSHpci:
2603eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRSHs:
2604eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2605eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2606eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2LDRDi8: {
2607eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rt = MI->getOperand(0).getReg();
2608eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned Rn = MI->getOperand(2).getReg();
2609eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return (Rt == Rn) ? 3 : 2;
2610eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2611eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2612eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRB_POST:
2613eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRB_PRE:
2614eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRBs:
2615eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRDi8:
2616eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRH_POST:
2617eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRH_PRE:
2618eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRHs:
2619eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STR_POST:
2620eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STR_PRE:
2621eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::t2STRs:
2622eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 2;
2623eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
2624eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson}
2625eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
26269eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// Return the number of 32-bit words loaded by LDM or stored by STM. If this
26279eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// can't be easily determined return 0 (missing MachineMemOperand).
26289eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick//
26299eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// FIXME: The current MachineInstr design does not support relying on machine
26309eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// mem operands to determine the width of a memory access. Instead, we expect
26319eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// the target to provide this information based on the instruction opcode and
26329eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// operands. However, using MachineMemOperand is a the best solution now for
26339eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// two reasons:
26349eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick//
26359eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// 1) getNumMicroOps tries to infer LDM memory width from the total number of MI
26369eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// operands. This is much more dangerous than using the MachineMemOperand
26379eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// sizes because CodeGen passes can insert/remove optional machine operands. In
26389eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// fact, it's totally incorrect for preRA passes and appears to be wrong for
26399eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// postRA passes as well.
26409eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick//
26419eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// 2) getNumLDMAddresses is only used by the scheduling machine model and any
26429eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// machine model that calls this should handle the unknown (zero size) case.
26439eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick//
26449eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// Long term, we should require a target hook that verifies MachineMemOperand
26459eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// sizes during MC lowering. That target hook should be local to MC lowering
26469eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// because we can't ensure that it is aware of other MI forms. Doing this will
26479eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick// ensure that MachineMemOperands are correctly propagated through all passes.
26489eed53379f19f836769a0c4a14042eeb1b587769Andrew Trickunsigned ARMBaseInstrInfo::getNumLDMAddresses(const MachineInstr *MI) const {
26499eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick  unsigned Size = 0;
26509eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick  for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
26519eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick         E = MI->memoperands_end(); I != E; ++I) {
26529eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick    Size += (*I)->getSize();
26539eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick  }
26549eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick  return Size / 4;
26559eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick}
26569eed53379f19f836769a0c4a14042eeb1b587769Andrew Trick
26575f54ce347368105260be2cec497b6a4199dc5789Evan Chengunsigned
26588239daf7c83a65a189c352cce3191cdc3bbfe151Evan ChengARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
26598239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                 const MachineInstr *MI) const {
26603ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng  if (!ItinData || ItinData->isEmpty())
26615f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    return 1;
26625f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
2663e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
26645f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  unsigned Class = Desc.getSchedClass();
2665218ee74a011c0d350099c452810da0bd57a15047Andrew Trick  int ItinUOps = ItinData->getNumMicroOps(Class);
2666eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  if (ItinUOps >= 0) {
2667eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Subtarget.isSwift() && (Desc.mayLoad() || Desc.mayStore()))
2668eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return getNumMicroOpsSwiftLdSt(ItinData, MI);
2669eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
2670218ee74a011c0d350099c452810da0bd57a15047Andrew Trick    return ItinUOps;
2671eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
26725f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
26735f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  unsigned Opc = MI->getOpcode();
26745f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  switch (Opc) {
26755f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  default:
26765f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    llvm_unreachable("Unexpected multi-uops instruction!");
267773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMQIA:
267873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMQIA:
26795f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    return 2;
26805f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
26815f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  // The number of uOps for load / store multiple are determined by the number
26825f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  // registers.
26836e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  //
26843ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng  // On Cortex-A8, each pair of register loads / stores can be scheduled on the
26853ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng  // same cycle. The scheduling for the first load / store must be done
2686c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru  // separately by assuming the address is not 64-bit aligned.
268773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  //
26883ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng  // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2). If the address
268973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  // is not 64-bit aligned, then AGU would take an extra cycle.  For VFP / NEON
269073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1.
269173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDIA:
269273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDIA_UPD:
269373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDDB_UPD:
269473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSIA:
269573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSIA_UPD:
269673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSDB_UPD:
269773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDIA:
269873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDIA_UPD:
269973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDDB_UPD:
270073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSIA:
270173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSIA_UPD:
270273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSDB_UPD: {
27035f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
27045f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    return (NumRegs / 2) + (NumRegs % 2) + 1;
27055f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  }
270673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
270773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA_RET:
270873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA:
270973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDA:
271073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDB:
271173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIB:
271273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA_UPD:
271373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDA_UPD:
271473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDB_UPD:
271573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIB_UPD:
271673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIA:
271773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDA:
271873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDB:
271973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIB:
272073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIA_UPD:
272173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDA_UPD:
272273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDB_UPD:
272373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIB_UPD:
272473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tLDMIA:
272573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tLDMIA_UPD:
272673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tSTMIA_UPD:
27275f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  case ARM::tPOP_RET:
27285f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  case ARM::tPOP:
27295f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  case ARM::tPUSH:
273073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA_RET:
273173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA:
273273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMDB:
273373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA_UPD:
273473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMDB_UPD:
273573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMIA:
273673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMDB:
273773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMIA_UPD:
273873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMDB_UPD: {
27393ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng    unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands() + 1;
2740eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Subtarget.isSwift()) {
2741eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      int UOps = 1 + NumRegs;  // One for address computation, one for each ld / st.
2742eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      switch (Opc) {
2743eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      default: break;
2744eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VLDMDIA_UPD:
2745eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VLDMDDB_UPD:
2746eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VLDMSIA_UPD:
2747eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VLDMSDB_UPD:
2748eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VSTMDIA_UPD:
2749eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VSTMDDB_UPD:
2750eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VSTMSIA_UPD:
2751eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::VSTMSDB_UPD:
2752eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::LDMIA_UPD:
2753eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::LDMDA_UPD:
2754eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::LDMDB_UPD:
2755eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::LDMIB_UPD:
2756eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::STMIA_UPD:
2757eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::STMDA_UPD:
2758eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::STMDB_UPD:
2759eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::STMIB_UPD:
2760eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::tLDMIA_UPD:
2761eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::tSTMIA_UPD:
2762eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::t2LDMIA_UPD:
2763eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::t2LDMDB_UPD:
2764eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::t2STMIA_UPD:
2765eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::t2STMDB_UPD:
2766eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        ++UOps; // One for base register writeback.
2767eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        break;
2768eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::LDMIA_RET:
2769eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::tPOP_RET:
2770eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      case ARM::t2LDMIA_RET:
2771eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        UOps += 2; // One for base reg wb, one for write to pc.
2772eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        break;
2773eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      }
2774eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return UOps;
2775eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    } else if (Subtarget.isCortexA8()) {
27768239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng      if (NumRegs < 4)
27778239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng        return 2;
27788239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng      // 4 registers would be issued: 2, 2.
27798239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng      // 5 registers would be issued: 2, 2, 1.
2780218ee74a011c0d350099c452810da0bd57a15047Andrew Trick      int A8UOps = (NumRegs / 2);
27818239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng      if (NumRegs % 2)
2782218ee74a011c0d350099c452810da0bd57a15047Andrew Trick        ++A8UOps;
2783218ee74a011c0d350099c452810da0bd57a15047Andrew Trick      return A8UOps;
2784eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
2785218ee74a011c0d350099c452810da0bd57a15047Andrew Trick      int A9UOps = (NumRegs / 2);
27863ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng      // If there are odd number of registers or if it's not 64-bit aligned,
27873ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng      // then it takes an extra AGU (Address Generation Unit) cycle.
27883ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng      if ((NumRegs % 2) ||
27893ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng          !MI->hasOneMemOperand() ||
27903ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng          (*MI->memoperands_begin())->getAlignment() < 8)
2791218ee74a011c0d350099c452810da0bd57a15047Andrew Trick        ++A9UOps;
2792218ee74a011c0d350099c452810da0bd57a15047Andrew Trick      return A9UOps;
27933ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng    } else {
27943ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng      // Assume the worst.
27953ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng      return NumRegs;
27962bbb76909126db5bed6bde84b16d94ab5de4d372Michael J. Spencer    }
27975f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  }
27985f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  }
27995f54ce347368105260be2cec497b6a4199dc5789Evan Cheng}
2800a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
2801a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Chengint
2802344d9db97062736cd66da6c07baa9108b6cfa419Evan ChengARMBaseInstrInfo::getVLDMDefCycle(const InstrItineraryData *ItinData,
2803e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                  const MCInstrDesc &DefMCID,
2804344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                  unsigned DefClass,
2805344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                  unsigned DefIdx, unsigned DefAlign) const {
2806e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  int RegNo = (int)(DefIdx+1) - DefMCID.getNumOperands() + 1;
2807344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (RegNo <= 0)
2808344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Def is the address writeback.
2809344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    return ItinData->getOperandCycle(DefClass, DefIdx);
2810344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2811344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int DefCycle;
2812344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (Subtarget.isCortexA8()) {
2813344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // (regno / 2) + (regno % 2) + 1
2814344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = RegNo / 2 + 1;
2815344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if (RegNo % 2)
2816344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++DefCycle;
2817eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
2818344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = RegNo;
2819344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    bool isSLoad = false;
282073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
2821e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    switch (DefMCID.getOpcode()) {
2822344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    default: break;
282373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VLDMSIA:
282473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VLDMSIA_UPD:
282573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VLDMSDB_UPD:
2826344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      isSLoad = true;
2827344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      break;
2828344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    }
282973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
2830344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // If there are odd number of 'S' registers or if it's not 64-bit aligned,
2831344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // then it takes an extra cycle.
2832344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
2833344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++DefCycle;
2834344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  } else {
2835344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Assume the worst.
2836344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = RegNo + 2;
2837344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  }
2838344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2839344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  return DefCycle;
2840344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng}
2841344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2842344d9db97062736cd66da6c07baa9108b6cfa419Evan Chengint
2843344d9db97062736cd66da6c07baa9108b6cfa419Evan ChengARMBaseInstrInfo::getLDMDefCycle(const InstrItineraryData *ItinData,
2844e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                 const MCInstrDesc &DefMCID,
2845344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                 unsigned DefClass,
2846344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                 unsigned DefIdx, unsigned DefAlign) const {
2847e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  int RegNo = (int)(DefIdx+1) - DefMCID.getNumOperands() + 1;
2848344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (RegNo <= 0)
2849344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Def is the address writeback.
2850344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    return ItinData->getOperandCycle(DefClass, DefIdx);
2851344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2852344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int DefCycle;
2853344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (Subtarget.isCortexA8()) {
2854344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // 4 registers would be issued: 1, 2, 1.
2855344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // 5 registers would be issued: 1, 2, 2.
2856344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = RegNo / 2;
2857344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if (DefCycle < 1)
2858344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      DefCycle = 1;
2859344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Result latency is issue cycle + 2: E2.
2860344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle += 2;
2861eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
2862344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = (RegNo / 2);
2863344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // If there are odd number of registers or if it's not 64-bit aligned,
2864344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // then it takes an extra AGU (Address Generation Unit) cycle.
2865344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if ((RegNo % 2) || DefAlign < 8)
2866344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++DefCycle;
2867344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Result latency is AGU cycles + 2.
2868344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle += 2;
2869344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  } else {
2870344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Assume the worst.
2871344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    DefCycle = RegNo + 2;
2872344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  }
2873344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2874344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  return DefCycle;
2875344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng}
2876344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2877344d9db97062736cd66da6c07baa9108b6cfa419Evan Chengint
2878344d9db97062736cd66da6c07baa9108b6cfa419Evan ChengARMBaseInstrInfo::getVSTMUseCycle(const InstrItineraryData *ItinData,
2879e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                  const MCInstrDesc &UseMCID,
2880344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                  unsigned UseClass,
2881344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                  unsigned UseIdx, unsigned UseAlign) const {
2882e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  int RegNo = (int)(UseIdx+1) - UseMCID.getNumOperands() + 1;
2883344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (RegNo <= 0)
2884344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    return ItinData->getOperandCycle(UseClass, UseIdx);
2885344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2886344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int UseCycle;
2887344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (Subtarget.isCortexA8()) {
2888344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // (regno / 2) + (regno % 2) + 1
2889344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = RegNo / 2 + 1;
2890344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if (RegNo % 2)
2891344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++UseCycle;
2892eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
2893344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = RegNo;
2894344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    bool isSStore = false;
289573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
2896e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    switch (UseMCID.getOpcode()) {
2897344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    default: break;
289873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VSTMSIA:
289973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VSTMSIA_UPD:
290073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    case ARM::VSTMSDB_UPD:
2901344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      isSStore = true;
2902344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      break;
2903344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    }
290473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
2905344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // If there are odd number of 'S' registers or if it's not 64-bit aligned,
2906344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // then it takes an extra cycle.
2907344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if ((isSStore && (RegNo % 2)) || UseAlign < 8)
2908344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++UseCycle;
2909344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  } else {
2910344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Assume the worst.
2911344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = RegNo + 2;
2912344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  }
2913344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2914344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  return UseCycle;
2915344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng}
2916344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2917344d9db97062736cd66da6c07baa9108b6cfa419Evan Chengint
2918344d9db97062736cd66da6c07baa9108b6cfa419Evan ChengARMBaseInstrInfo::getSTMUseCycle(const InstrItineraryData *ItinData,
2919e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                 const MCInstrDesc &UseMCID,
2920344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                 unsigned UseClass,
2921344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                                 unsigned UseIdx, unsigned UseAlign) const {
2922e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  int RegNo = (int)(UseIdx+1) - UseMCID.getNumOperands() + 1;
2923344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (RegNo <= 0)
2924344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    return ItinData->getOperandCycle(UseClass, UseIdx);
2925344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2926344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int UseCycle;
2927344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  if (Subtarget.isCortexA8()) {
2928344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = RegNo / 2;
2929344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if (UseCycle < 2)
2930344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      UseCycle = 2;
2931344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Read in E3.
2932344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle += 2;
2933eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
2934344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = (RegNo / 2);
2935344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // If there are odd number of registers or if it's not 64-bit aligned,
2936344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // then it takes an extra AGU (Address Generation Unit) cycle.
2937344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    if ((RegNo % 2) || UseAlign < 8)
2938344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng      ++UseCycle;
2939344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  } else {
2940344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    // Assume the worst.
2941344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    UseCycle = 1;
2942344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  }
2943344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  return UseCycle;
2944344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng}
2945344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng
2946344d9db97062736cd66da6c07baa9108b6cfa419Evan Chengint
2947a0792de66c8364d47b0a688c7f408efb7b10f31bEvan ChengARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
2948e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                    const MCInstrDesc &DefMCID,
2949a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                                    unsigned DefIdx, unsigned DefAlign,
2950e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                    const MCInstrDesc &UseMCID,
2951a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                                    unsigned UseIdx, unsigned UseAlign) const {
2952e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned DefClass = DefMCID.getSchedClass();
2953e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned UseClass = UseMCID.getSchedClass();
2954a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
2955e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (DefIdx < DefMCID.getNumDefs() && UseIdx < UseMCID.getNumOperands())
2956a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
2957a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
2958a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  // This may be a def / use of a variable_ops instruction, the operand
2959a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  // latency might be determinable dynamically. Let the target try to
2960a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  // figure it out.
29619e08ee5d16b596078e20787f0b5f36121f099333Evan Cheng  int DefCycle = -1;
29627e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  bool LdmBypass = false;
2963e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  switch (DefMCID.getOpcode()) {
2964a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  default:
2965a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
2966a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    break;
296773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
296873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDIA:
296973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDIA_UPD:
297073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMDDB_UPD:
297173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSIA:
297273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSIA_UPD:
297373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMSDB_UPD:
2974e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
29755a50ceeaea980962c1982ad535226c7ab06c971cEvan Cheng    break;
297673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
297773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA_RET:
297873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA:
297973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDA:
298073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDB:
298173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIB:
298273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIA_UPD:
298373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDA_UPD:
298473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMDB_UPD:
298573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::LDMIB_UPD:
298673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tLDMIA:
298773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tLDMIA_UPD:
2988a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  case ARM::tPUSH:
298973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA_RET:
299073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA:
299173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMDB:
299273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMIA_UPD:
299373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2LDMDB_UPD:
2994a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    LdmBypass = 1;
2995e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
2996344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng    break;
2997a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  }
2998a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
2999a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  if (DefCycle == -1)
3000a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    // We can't seem to determine the result latency of the def, assume it's 2.
3001a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    DefCycle = 2;
3002a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3003a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  int UseCycle = -1;
3004e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  switch (UseMCID.getOpcode()) {
3005a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  default:
3006a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    UseCycle = ItinData->getOperandCycle(UseClass, UseIdx);
3007a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    break;
300873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
300973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDIA:
301073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDIA_UPD:
301173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMDDB_UPD:
301273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSIA:
301373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSIA_UPD:
301473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMSDB_UPD:
3015e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
30165a50ceeaea980962c1982ad535226c7ab06c971cEvan Cheng    break;
301773fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling
301873fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIA:
301973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDA:
302073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDB:
302173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIB:
302273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIA_UPD:
302373fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDA_UPD:
302473fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMDB_UPD:
302573fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::STMIB_UPD:
302673fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::tSTMIA_UPD:
3027a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  case ARM::tPOP_RET:
3028a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  case ARM::tPOP:
302973fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMIA:
303073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMDB:
303173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMIA_UPD:
303273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::t2STMDB_UPD:
3033e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
30345a50ceeaea980962c1982ad535226c7ab06c971cEvan Cheng    break;
3035a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  }
3036a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3037a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  if (UseCycle == -1)
3038a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    // Assume it's read in the first stage.
3039a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    UseCycle = 1;
3040a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3041a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  UseCycle = DefCycle - UseCycle + 1;
3042a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  if (UseCycle > 0) {
3043a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    if (LdmBypass) {
3044a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng      // It's a variable_ops instruction so we can't use DefIdx here. Just use
3045a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng      // first def operand.
3046e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      if (ItinData->hasPipelineForwarding(DefClass, DefMCID.getNumOperands()-1,
3047a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                                          UseClass, UseIdx))
3048a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng        --UseCycle;
3049a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    } else if (ItinData->hasPipelineForwarding(DefClass, DefIdx,
305073fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling                                               UseClass, UseIdx)) {
3051a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng      --UseCycle;
305273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling    }
3053a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  }
3054a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3055a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  return UseCycle;
3056a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng}
3057a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3058ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Chengstatic const MachineInstr *getBundledDefMI(const TargetRegisterInfo *TRI,
3059020f4106f820648fd7e91956859844a80de13974Evan Cheng                                           const MachineInstr *MI, unsigned Reg,
3060ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng                                           unsigned &DefIdx, unsigned &Dist) {
3061ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  Dist = 0;
3062ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3063ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_iterator I = MI; ++I;
3064ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_instr_iterator II =
3065ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    llvm::prior(I.getInstrIterator());
3066ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  assert(II->isInsideBundle() && "Empty bundle?");
3067ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3068ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  int Idx = -1;
3069ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  while (II->isInsideBundle()) {
3070ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    Idx = II->findRegisterDefOperandIdx(Reg, false, true, TRI);
3071ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    if (Idx != -1)
3072ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      break;
3073ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    --II;
3074ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    ++Dist;
3075ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  }
3076ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3077ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  assert(Idx != -1 && "Cannot find bundled definition!");
3078ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  DefIdx = Idx;
3079ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  return II;
3080ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng}
3081ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3082ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Chengstatic const MachineInstr *getBundledUseMI(const TargetRegisterInfo *TRI,
3083020f4106f820648fd7e91956859844a80de13974Evan Cheng                                           const MachineInstr *MI, unsigned Reg,
3084ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng                                           unsigned &UseIdx, unsigned &Dist) {
3085ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  Dist = 0;
3086ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3087ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_instr_iterator II = MI; ++II;
3088ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  assert(II->isInsideBundle() && "Empty bundle?");
3089ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
3090ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3091ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  // FIXME: This doesn't properly handle multiple uses.
3092ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  int Idx = -1;
3093ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  while (II != E && II->isInsideBundle()) {
3094ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    Idx = II->findRegisterUseOperandIdx(Reg, false, TRI);
3095ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    if (Idx != -1)
3096ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      break;
3097ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    if (II->getOpcode() != ARM::t2IT)
3098ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      ++Dist;
3099ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    ++II;
3100ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  }
3101ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3102020f4106f820648fd7e91956859844a80de13974Evan Cheng  if (Idx == -1) {
3103020f4106f820648fd7e91956859844a80de13974Evan Cheng    Dist = 0;
3104020f4106f820648fd7e91956859844a80de13974Evan Cheng    return 0;
3105020f4106f820648fd7e91956859844a80de13974Evan Cheng  }
3106020f4106f820648fd7e91956859844a80de13974Evan Cheng
3107ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  UseIdx = Idx;
3108ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  return II;
3109ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng}
3110ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
311168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick/// Return the number of cycles to add to (or subtract from) the static
311268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick/// itinerary based on the def opcode and alignment. The caller will ensure that
311368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick/// adjusted latency is at least one cycle.
311468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trickstatic int adjustDefLatency(const ARMSubtarget &Subtarget,
311568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                            const MachineInstr *DefMI,
311668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                            const MCInstrDesc *DefMCID, unsigned DefAlign) {
311768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  int Adjust = 0;
3118616471d4bfe4717fa86259ff4534703357b3b723Silviu Baranga  if (Subtarget.isCortexA8() || Subtarget.isLikeA9()) {
31197e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
31207e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    // variants are one cycle cheaper.
3121ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    switch (DefMCID->getOpcode()) {
31227e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    default: break;
3123cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::LDRrs:
3124cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::LDRBrs: {
31257e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShOpVal = DefMI->getOperand(3).getImm();
31267e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
31277e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      if (ShImm == 0 ||
31287e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng          (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
312968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick        --Adjust;
31307e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      break;
31317e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
3132cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRs:
3133cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRBs:
3134cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRHs:
31357e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    case ARM::t2LDRSHs: {
31367e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      // Thumb2 mode: lsl only.
31377e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShAmt = DefMI->getOperand(3).getImm();
31387e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      if (ShAmt == 0 || ShAmt == 2)
313968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick        --Adjust;
31407e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      break;
31417e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
31427e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
3143eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (Subtarget.isSwift()) {
3144eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // FIXME: Properly handle all of the latency adjustments for address
3145eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // writeback.
3146eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    switch (DefMCID->getOpcode()) {
3147eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    default: break;
3148eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::LDRrs:
3149eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::LDRBrs: {
3150eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      unsigned ShOpVal = DefMI->getOperand(3).getImm();
3151eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3152eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3153eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      if (!isSub &&
3154eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          (ShImm == 0 ||
3155eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson           ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3156eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson            ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3157eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        Adjust -= 2;
3158eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      else if (!isSub &&
3159eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson               ShImm == 1 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsr)
3160eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        --Adjust;
3161eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      break;
3162eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
3163eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRs:
3164eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRBs:
3165eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRHs:
3166eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRSHs: {
3167eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      // Thumb2 mode: lsl only.
3168eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      unsigned ShAmt = DefMI->getOperand(3).getImm();
3169eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
3170eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        Adjust -= 2;
3171eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      break;
3172eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
3173eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
31747e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  }
31757e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng
3176616471d4bfe4717fa86259ff4534703357b3b723Silviu Baranga  if (DefAlign < 8 && Subtarget.isLikeA9()) {
3177ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    switch (DefMCID->getOpcode()) {
317875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    default: break;
317975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1q8:
318075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1q16:
318175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1q32:
318275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1q64:
318310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_fixed:
318410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_fixed:
318510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_fixed:
318610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_fixed:
318710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_register:
318810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_register:
318910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_register:
319010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_register:
319175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2d8:
319275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2d16:
319375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2d32:
319475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q8:
319575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q16:
319675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q32:
3197a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_fixed:
3198a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_fixed:
3199a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_fixed:
3200a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_fixed:
3201a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_fixed:
3202a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_fixed:
3203a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_register:
3204a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_register:
3205a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_register:
3206a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_register:
3207a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_register:
3208a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_register:
320975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d8:
321075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d16:
321175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d32:
321275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1d64T:
321375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d8_UPD:
321475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d16_UPD:
321575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d32_UPD:
32165921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_fixed:
32175921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_register:
321875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q8_UPD:
321975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q16_UPD:
322075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q32_UPD:
322175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d8:
322275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d16:
322375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d32:
322475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1d64Q:
322575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d8_UPD:
322675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d16_UPD:
322775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d32_UPD:
3228399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_fixed:
3229399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_register:
323075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q8_UPD:
323175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q16_UPD:
323275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q32_UPD:
323375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1DUPq8:
323475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1DUPq16:
323575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1DUPq32:
3236096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq8wb_fixed:
3237096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq16wb_fixed:
3238096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq32wb_fixed:
3239096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq8wb_register:
3240096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq16wb_register:
3241096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    case ARM::VLD1DUPq32wb_register:
324275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2DUPd8:
324375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2DUPd16:
324475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2DUPd32:
3245e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd8wb_fixed:
3246e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd16wb_fixed:
3247e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd32wb_fixed:
3248e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd8wb_register:
3249e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd16wb_register:
3250e6949b13997e6d31aa4719a0e80c4b6b405e42a9Jim Grosbach    case ARM::VLD2DUPd32wb_register:
325175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd8:
325275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd16:
325375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd32:
325475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd8_UPD:
325575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd16_UPD:
325675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd32_UPD:
325775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd8:
325875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd16:
325975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd32:
326075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd8_UPD:
326175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd16_UPD:
326275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNd32_UPD:
326375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd8:
326475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd16:
326575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd32:
326675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq16:
326775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq32:
326875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd8_UPD:
326975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd16_UPD:
327075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd32_UPD:
327175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq16_UPD:
327275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq32_UPD:
327375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd8:
327475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd16:
327575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd32:
327675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq16:
327775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq32:
327875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd8_UPD:
327975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd16_UPD:
328075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd32_UPD:
328175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq16_UPD:
328275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq32_UPD:
328375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      // If the address is not 64-bit aligned, the latencies of these
328475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      // instructions increases by one.
328568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick      ++Adjust;
328675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      break;
328775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    }
328868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
328968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  return Adjust;
329068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick}
329168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
329275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng
329368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
329468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trickint
329568b16541cc58411c7b0607ca4c0fb497222b668dAndrew TrickARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
329668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                                    const MachineInstr *DefMI, unsigned DefIdx,
329768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                                    const MachineInstr *UseMI,
329868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                                    unsigned UseIdx) const {
329968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // No operand latency. The caller may fall back to getInstrLatency.
330068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (!ItinData || ItinData->isEmpty())
330168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return -1;
330268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
330368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  const MachineOperand &DefMO = DefMI->getOperand(DefIdx);
330468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned Reg = DefMO.getReg();
330568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  const MCInstrDesc *DefMCID = &DefMI->getDesc();
330668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  const MCInstrDesc *UseMCID = &UseMI->getDesc();
330768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
330868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned DefAdj = 0;
330968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (DefMI->isBundle()) {
331068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    DefMI = getBundledDefMI(&getRegisterInfo(), DefMI, Reg, DefIdx, DefAdj);
331168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    DefMCID = &DefMI->getDesc();
331268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
331368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (DefMI->isCopyLike() || DefMI->isInsertSubreg() ||
331468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick      DefMI->isRegSequence() || DefMI->isImplicitDef()) {
331568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return 1;
331668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
331768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
331868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned UseAdj = 0;
331968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (UseMI->isBundle()) {
332068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    unsigned NewUseIdx;
332168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    const MachineInstr *NewUseMI = getBundledUseMI(&getRegisterInfo(), UseMI,
332268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                                                   Reg, NewUseIdx, UseAdj);
3323e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick    if (!NewUseMI)
3324e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick      return -1;
3325e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick
3326e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick    UseMI = NewUseMI;
3327e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick    UseIdx = NewUseIdx;
3328e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick    UseMCID = &UseMI->getDesc();
332968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
333068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
333168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (Reg == ARM::CPSR) {
333268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    if (DefMI->getOpcode() == ARM::FMSTAT) {
333368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick      // fpscr -> cpsr stalls over 20 cycles on A8 (and earlier?)
3334616471d4bfe4717fa86259ff4534703357b3b723Silviu Baranga      return Subtarget.isLikeA9() ? 1 : 20;
333568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    }
333668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
333768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // CPSR set and branch can be paired in the same cycle.
333868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    if (UseMI->isBranch())
333968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick      return 0;
334068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
334168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // Otherwise it takes the instruction latency (generally one).
334268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    unsigned Latency = getInstrLatency(ItinData, DefMI);
334368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
334468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // For Thumb2 and -Os, prefer scheduling CPSR setting instruction close to
334568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // its uses. Instructions which are otherwise scheduled between them may
334668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // incur a code size penalty (not able to use the CPSR setting 16-bit
334768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    // instructions).
334868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    if (Latency > 0 && Subtarget.isThumb2()) {
334968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick      const MachineFunction *MF = DefMI->getParent()->getParent();
3350831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling      if (MF->getFunction()->getAttributes().
3351831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling            hasAttribute(AttributeSet::FunctionIndex,
3352831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling                         Attribute::OptimizeForSize))
335368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick        --Latency;
335468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    }
335568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return Latency;
335668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
335768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
3358e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick  if (DefMO.isImplicit() || UseMI->getOperand(UseIdx).isImplicit())
3359e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick    return -1;
3360e2b32bb20ee76f24708b3c9e19b6fbc651c25637Andrew Trick
336168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned DefAlign = DefMI->hasOneMemOperand()
336268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    ? (*DefMI->memoperands_begin())->getAlignment() : 0;
336368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned UseAlign = UseMI->hasOneMemOperand()
336468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    ? (*UseMI->memoperands_begin())->getAlignment() : 0;
336568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
336668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Get the itinerary's latency if possible, and handle variable_ops.
336768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  int Latency = getOperandLatency(ItinData, *DefMCID, DefIdx, DefAlign,
336868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick                                  *UseMCID, UseIdx, UseAlign);
336968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Unable to find operand latency. The caller may resort to getInstrLatency.
337068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (Latency < 0)
337168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return Latency;
337268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
337368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Adjust for IT block position.
337468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  int Adj = DefAdj + UseAdj;
337568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
337668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Adjust for dynamic def-side opcode variants not captured by the itinerary.
337768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  Adj += adjustDefLatency(Subtarget, DefMI, DefMCID, DefAlign);
337868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (Adj >= 0 || (int)Latency > -Adj) {
337968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return Latency + Adj;
338068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
338168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Return the itinerary latency, which may be zero but not less than zero.
33827e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  return Latency;
3383a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng}
3384a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3385a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Chengint
3386a0792de66c8364d47b0a688c7f408efb7b10f31bEvan ChengARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
3387a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                                    SDNode *DefNode, unsigned DefIdx,
3388a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                                    SDNode *UseNode, unsigned UseIdx) const {
3389a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  if (!DefNode->isMachineOpcode())
3390a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    return 1;
3391a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3392e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &DefMCID = get(DefNode->getMachineOpcode());
3393c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick
3394e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (isZeroCost(DefMCID.Opcode))
3395c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick    return 0;
3396c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick
3397a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  if (!ItinData || ItinData->isEmpty())
3398e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    return DefMCID.mayLoad() ? 3 : 1;
3399a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3400089751535d6e9adf65842e2ca5867bf9a70e1e95Evan Cheng  if (!UseNode->isMachineOpcode()) {
3401e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    int Latency = ItinData->getOperandCycle(DefMCID.getSchedClass(), DefIdx);
3402eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (Subtarget.isLikeA9() || Subtarget.isSwift())
3403089751535d6e9adf65842e2ca5867bf9a70e1e95Evan Cheng      return Latency <= 2 ? 1 : Latency - 1;
3404089751535d6e9adf65842e2ca5867bf9a70e1e95Evan Cheng    else
3405089751535d6e9adf65842e2ca5867bf9a70e1e95Evan Cheng      return Latency <= 3 ? 1 : Latency - 2;
3406089751535d6e9adf65842e2ca5867bf9a70e1e95Evan Cheng  }
3407a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
3408e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &UseMCID = get(UseNode->getMachineOpcode());
3409a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  const MachineSDNode *DefMN = dyn_cast<MachineSDNode>(DefNode);
3410a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  unsigned DefAlign = !DefMN->memoperands_empty()
3411a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    ? (*DefMN->memoperands_begin())->getAlignment() : 0;
3412a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  const MachineSDNode *UseMN = dyn_cast<MachineSDNode>(UseNode);
3413a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  unsigned UseAlign = !UseMN->memoperands_empty()
3414a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng    ? (*UseMN->memoperands_begin())->getAlignment() : 0;
3415e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  int Latency = getOperandLatency(ItinData, DefMCID, DefIdx, DefAlign,
3416e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                  UseMCID, UseIdx, UseAlign);
34177e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng
34187e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  if (Latency > 1 &&
3419616471d4bfe4717fa86259ff4534703357b3b723Silviu Baranga      (Subtarget.isCortexA8() || Subtarget.isLikeA9())) {
34207e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
34217e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    // variants are one cycle cheaper.
3422e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    switch (DefMCID.getOpcode()) {
34237e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    default: break;
3424cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::LDRrs:
3425cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::LDRBrs: {
34267e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShOpVal =
34277e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng        cast<ConstantSDNode>(DefNode->getOperand(2))->getZExtValue();
34287e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
34297e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      if (ShImm == 0 ||
34307e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng          (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
34317e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng        --Latency;
34327e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      break;
34337e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
3434cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRs:
3435cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRBs:
3436cff9baa95273bc279bf5fadb9e27afbd25cca20bJakob Stoklund Olesen    case ARM::t2LDRHs:
34377e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    case ARM::t2LDRSHs: {
34387e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      // Thumb2 mode: lsl only.
34397e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      unsigned ShAmt =
34407e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng        cast<ConstantSDNode>(DefNode->getOperand(2))->getZExtValue();
34417e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      if (ShAmt == 0 || ShAmt == 2)
34427e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng        --Latency;
34437e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng      break;
34447e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
34457e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng    }
3446eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (DefIdx == 0 && Latency > 2 && Subtarget.isSwift()) {
3447eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // FIXME: Properly handle all of the latency adjustments for address
3448eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // writeback.
3449eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    switch (DefMCID.getOpcode()) {
3450eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    default: break;
3451eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::LDRrs:
3452eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::LDRBrs: {
3453eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      unsigned ShOpVal =
3454eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        cast<ConstantSDNode>(DefNode->getOperand(2))->getZExtValue();
3455eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3456eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      if (ShImm == 0 ||
3457eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson          ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3458eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson           ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
3459eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        Latency -= 2;
3460eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      else if (ShImm == 1 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsr)
3461eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson        --Latency;
3462eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      break;
3463eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
3464eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRs:
3465eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRBs:
3466eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRHs:
3467eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    case ARM::t2LDRSHs: {
3468eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      // Thumb2 mode: lsl 0-3 only.
3469eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      Latency -= 2;
3470eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      break;
3471eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
3472eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    }
34737e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  }
34747e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng
3475616471d4bfe4717fa86259ff4534703357b3b723Silviu Baranga  if (DefAlign < 8 && Subtarget.isLikeA9())
3476e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    switch (DefMCID.getOpcode()) {
347775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    default: break;
347828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q8:
347928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q16:
348028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q32:
348128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q64:
348228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q8wb_register:
348328f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q16wb_register:
348428f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q32wb_register:
348528f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q64wb_register:
348628f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q8wb_fixed:
348728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q16wb_fixed:
348828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q32wb_fixed:
348928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD1q64wb_fixed:
349028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d8:
349128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d16:
349228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d32:
349375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q8Pseudo:
349475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q16Pseudo:
349575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2q32Pseudo:
349628f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d8wb_fixed:
349728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d16wb_fixed:
349828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d32wb_fixed:
3499a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8PseudoWB_fixed:
3500a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16PseudoWB_fixed:
3501a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32PseudoWB_fixed:
350228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d8wb_register:
350328f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d16wb_register:
350428f08c93e75d291695ea89b9004145103292e85bJim Grosbach    case ARM::VLD2d32wb_register:
3505a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8PseudoWB_register:
3506a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16PseudoWB_register:
3507a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32PseudoWB_register:
350875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d8Pseudo:
350975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d16Pseudo:
351075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d32Pseudo:
351175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1d64TPseudo:
351275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d8Pseudo_UPD:
351375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d16Pseudo_UPD:
351475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3d32Pseudo_UPD:
351575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q8Pseudo_UPD:
351675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q16Pseudo_UPD:
351775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q32Pseudo_UPD:
351875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q8oddPseudo:
351975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q16oddPseudo:
352075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q32oddPseudo:
352175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q8oddPseudo_UPD:
352275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q16oddPseudo_UPD:
352375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD3q32oddPseudo_UPD:
352475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d8Pseudo:
352575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d16Pseudo:
352675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d32Pseudo:
352775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1d64QPseudo:
352875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d8Pseudo_UPD:
352975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d16Pseudo_UPD:
353075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4d32Pseudo_UPD:
353175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q8Pseudo_UPD:
353275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q16Pseudo_UPD:
353375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q32Pseudo_UPD:
353475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q8oddPseudo:
353575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q16oddPseudo:
353675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q32oddPseudo:
353775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q8oddPseudo_UPD:
353875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q16oddPseudo_UPD:
353975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4q32oddPseudo_UPD:
3540c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq8:
3541c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq16:
3542c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq32:
3543c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq8wb_fixed:
3544c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq16wb_fixed:
3545c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq32wb_fixed:
3546c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq8wb_register:
3547c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq16wb_register:
3548c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD1DUPq32wb_register:
3549c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd8:
3550c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd16:
3551c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd32:
3552c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd8wb_fixed:
3553c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd16wb_fixed:
3554c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd32wb_fixed:
3555c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd8wb_register:
3556c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd16wb_register:
3557c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    case ARM::VLD2DUPd32wb_register:
355875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd8Pseudo:
355975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd16Pseudo:
356075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd32Pseudo:
356175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd8Pseudo_UPD:
356275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd16Pseudo_UPD:
356375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4DUPd32Pseudo_UPD:
356475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq8Pseudo:
356575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq16Pseudo:
356675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq32Pseudo:
356775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq8Pseudo_UPD:
356875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq16Pseudo_UPD:
356975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD1LNq32Pseudo_UPD:
357075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd8Pseudo:
357175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd16Pseudo:
357275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd32Pseudo:
357375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq16Pseudo:
357475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq32Pseudo:
357575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd8Pseudo_UPD:
357675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd16Pseudo_UPD:
357775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNd32Pseudo_UPD:
357875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq16Pseudo_UPD:
357975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD2LNq32Pseudo_UPD:
358075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd8Pseudo:
358175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd16Pseudo:
358275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd32Pseudo:
358375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq16Pseudo:
358475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq32Pseudo:
358575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd8Pseudo_UPD:
358675b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd16Pseudo_UPD:
358775b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNd32Pseudo_UPD:
358875b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq16Pseudo_UPD:
358975b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    case ARM::VLD4LNq32Pseudo_UPD:
359075b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      // If the address is not 64-bit aligned, the latencies of these
359175b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      // instructions increases by one.
359275b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      ++Latency;
359375b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng      break;
359475b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng    }
359575b41f1540f35ef0fd5e4a52c1840f1a19debb03Evan Cheng
35967e2fe9150f905167f6685c9730911c2abc08293cEvan Cheng  return Latency;
3597a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng}
35982312842de0c641107dd04d7e056d02491cc781caEvan Cheng
3599b7e0289fb320c8440ba5eed121a8b932dbd806a2Andrew Trickunsigned ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
3600b7e0289fb320c8440ba5eed121a8b932dbd806a2Andrew Trick                                           const MachineInstr *MI,
3601b7e0289fb320c8440ba5eed121a8b932dbd806a2Andrew Trick                                           unsigned *PredCost) const {
36028239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  if (MI->isCopyLike() || MI->isInsertSubreg() ||
36038239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng      MI->isRegSequence() || MI->isImplicitDef())
36048239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    return 1;
36058239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
3606ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // An instruction scheduler typically runs on unbundled instructions, however
3607ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // other passes may query the latency of a bundled instruction.
3608ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  if (MI->isBundle()) {
3609ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick    unsigned Latency = 0;
3610ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    MachineBasicBlock::const_instr_iterator I = MI;
3611ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
3612ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    while (++I != E && I->isInsideBundle()) {
3613ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng      if (I->getOpcode() != ARM::t2IT)
3614ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng        Latency += getInstrLatency(ItinData, I, PredCost);
3615ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    }
3616ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    return Latency;
3617ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng  }
3618ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
3619e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI->getDesc();
3620ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  if (PredCost && (MCID.isCall() || MCID.hasImplicitDefOfPhysReg(ARM::CPSR))) {
36218239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    // When predicated, CPSR is an additional source operand for CPSR updating
36228239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    // instructions, this apparently increases their latencies.
36238239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    *PredCost = 1;
3624ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  }
3625ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // Be sure to call getStageLatency for an empty itinerary in case it has a
3626ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // valid MinLatency property.
3627ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  if (!ItinData)
3628ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick    return MI->mayLoad() ? 3 : 1;
3629ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick
3630ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  unsigned Class = MCID.getSchedClass();
3631ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick
3632ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // For instructions with variable uops, use uops as latency.
363314ccc7b963861a856b593cc4fff62decd8ce248aAndrew Trick  if (!ItinData->isEmpty() && ItinData->getNumMicroOps(Class) < 0)
3634ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick    return getNumMicroOps(ItinData, MI);
363514ccc7b963861a856b593cc4fff62decd8ce248aAndrew Trick
3636ed7a51e69209af87f3749d5f95740f69a1dc7711Andrew Trick  // For the common case, fall back on the itinerary's latency.
363768b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned Latency = ItinData->getStageLatency(Class);
363868b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick
363968b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  // Adjust for dynamic def-side opcode variants not captured by the itinerary.
364068b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  unsigned DefAlign = MI->hasOneMemOperand()
364168b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    ? (*MI->memoperands_begin())->getAlignment() : 0;
364268b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  int Adj = adjustDefLatency(Subtarget, MI, &MCID, DefAlign);
364368b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  if (Adj >= 0 || (int)Latency > -Adj) {
364468b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick    return Latency + Adj;
364568b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  }
364668b16541cc58411c7b0607ca4c0fb497222b668dAndrew Trick  return Latency;
36478239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng}
36488239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
36498239daf7c83a65a189c352cce3191cdc3bbfe151Evan Chengint ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
36508239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                      SDNode *Node) const {
36518239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  if (!Node->isMachineOpcode())
36528239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    return 1;
36538239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
36548239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  if (!ItinData || ItinData->isEmpty())
36558239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    return 1;
36568239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
36578239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  unsigned Opcode = Node->getMachineOpcode();
36588239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  switch (Opcode) {
36598239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  default:
36608239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    return ItinData->getStageLatency(get(Opcode).getSchedClass());
366173fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VLDMQIA:
366273fe34a3ee866867d5028f4a9afa2c3b8efebcbaBill Wendling  case ARM::VSTMQIA:
36638239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng    return 2;
36648b3ca6216d62bf3f729c2e122dcfeb7c4d7500dcEric Christopher  }
36658239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng}
36668239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
36672312842de0c641107dd04d7e056d02491cc781caEvan Chengbool ARMBaseInstrInfo::
36682312842de0c641107dd04d7e056d02491cc781caEvan ChenghasHighOperandLatency(const InstrItineraryData *ItinData,
36692312842de0c641107dd04d7e056d02491cc781caEvan Cheng                      const MachineRegisterInfo *MRI,
36702312842de0c641107dd04d7e056d02491cc781caEvan Cheng                      const MachineInstr *DefMI, unsigned DefIdx,
36712312842de0c641107dd04d7e056d02491cc781caEvan Cheng                      const MachineInstr *UseMI, unsigned UseIdx) const {
36722312842de0c641107dd04d7e056d02491cc781caEvan Cheng  unsigned DDomain = DefMI->getDesc().TSFlags & ARMII::DomainMask;
36732312842de0c641107dd04d7e056d02491cc781caEvan Cheng  unsigned UDomain = UseMI->getDesc().TSFlags & ARMII::DomainMask;
36742312842de0c641107dd04d7e056d02491cc781caEvan Cheng  if (Subtarget.isCortexA8() &&
36752312842de0c641107dd04d7e056d02491cc781caEvan Cheng      (DDomain == ARMII::DomainVFP || UDomain == ARMII::DomainVFP))
36762312842de0c641107dd04d7e056d02491cc781caEvan Cheng    // CortexA8 VFP instructions are not pipelined.
36772312842de0c641107dd04d7e056d02491cc781caEvan Cheng    return true;
36782312842de0c641107dd04d7e056d02491cc781caEvan Cheng
36792312842de0c641107dd04d7e056d02491cc781caEvan Cheng  // Hoist VFP / NEON instructions with 4 or higher latency.
3680b86a0cdb674549d8493043331cecd9cbf53b80daAndrew Trick  int Latency = computeOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
3681f377071bf8393d35797107c753da3e84aea94ebeAndrew Trick  if (Latency < 0)
3682f377071bf8393d35797107c753da3e84aea94ebeAndrew Trick    Latency = getInstrLatency(ItinData, DefMI);
36832312842de0c641107dd04d7e056d02491cc781caEvan Cheng  if (Latency <= 3)
36842312842de0c641107dd04d7e056d02491cc781caEvan Cheng    return false;
36852312842de0c641107dd04d7e056d02491cc781caEvan Cheng  return DDomain == ARMII::DomainVFP || DDomain == ARMII::DomainNEON ||
36862312842de0c641107dd04d7e056d02491cc781caEvan Cheng         UDomain == ARMII::DomainVFP || UDomain == ARMII::DomainNEON;
36872312842de0c641107dd04d7e056d02491cc781caEvan Cheng}
3688c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng
3689c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Chengbool ARMBaseInstrInfo::
3690c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan ChenghasLowDefLatency(const InstrItineraryData *ItinData,
3691c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng                 const MachineInstr *DefMI, unsigned DefIdx) const {
3692c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  if (!ItinData || ItinData->isEmpty())
3693c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng    return false;
3694c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng
3695c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  unsigned DDomain = DefMI->getDesc().TSFlags & ARMII::DomainMask;
3696c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  if (DDomain == ARMII::DomainGeneral) {
3697c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng    unsigned DefClass = DefMI->getDesc().getSchedClass();
3698c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng    int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
3699c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng    return (DefCycle != -1 && DefCycle <= 2);
3700c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  }
3701c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  return false;
3702c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng}
370348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
37043be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trickbool ARMBaseInstrInfo::verifyInstruction(const MachineInstr *MI,
37053be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick                                         StringRef &ErrInfo) const {
37063be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  if (convertAddSubFlagsOpcode(MI->getOpcode())) {
37073be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick    ErrInfo = "Pseudo flag setting opcodes only exist in Selection DAG";
37083be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick    return false;
37093be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  }
37103be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  return true;
37113be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick}
37123be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
371348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Chengbool
371448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan ChengARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
371548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng                                     unsigned &AddSubOpc,
371648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng                                     bool &NegAcc, bool &HasLane) const {
371748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  DenseMap<unsigned, unsigned>::const_iterator I = MLxEntryMap.find(Opcode);
371848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  if (I == MLxEntryMap.end())
371948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    return false;
372048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
372148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  const ARM_MLxEntry &Entry = ARM_MLxTable[I->second];
372248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  MulOpc = Entry.MulOpc;
372348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  AddSubOpc = Entry.AddSubOpc;
372448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  NegAcc = Entry.NegAcc;
372548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  HasLane = Entry.HasLane;
372648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  return true;
372748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng}
372813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
372913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//===----------------------------------------------------------------------===//
373013fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// Execution domains.
373113fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//===----------------------------------------------------------------------===//
373213fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//
373313fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// Some instructions go down the NEON pipeline, some go down the VFP pipeline,
373413fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// and some can go down both.  The vmov instructions go down the VFP pipeline,
373513fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// but they can be changed to vorr equivalents that are executed by the NEON
373613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// pipeline.
373713fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//
373813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// We use the following execution domain numbering:
373913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//
37408bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesenenum ARMExeDomain {
37418bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen  ExeGeneric = 0,
37428bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen  ExeVFP = 1,
37438bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen  ExeNEON = 2
37448bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen};
374513fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//
374613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen// Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h
374713fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen//
374813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesenstd::pair<uint16_t, uint16_t>
374913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund OlesenARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const {
37503c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  // VMOVD, VMOVRS and VMOVSR are VFP instructions, but can be changed to NEON
37513c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  // if they are not predicated.
375213fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI))
37538bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen    return std::make_pair(ExeVFP, (1<<ExeVFP) | (1<<ExeNEON));
375413fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
3755a210db781f17b5ab8e2b71d53276153a9d15eeadSilviu Baranga  // CortexA9 is particularly picky about mixing the two and wants these
37563c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  // converted.
3757a210db781f17b5ab8e2b71d53276153a9d15eeadSilviu Baranga  if (Subtarget.isCortexA9() && !isPredicated(MI) &&
37583c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      (MI->getOpcode() == ARM::VMOVRS ||
3759c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover       MI->getOpcode() == ARM::VMOVSR ||
3760c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover       MI->getOpcode() == ARM::VMOVS))
37613c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover    return std::make_pair(ExeVFP, (1<<ExeVFP) | (1<<ExeNEON));
37623c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
376313fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  // No other instructions can be swizzled, so just determine their domain.
376413fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  unsigned Domain = MI->getDesc().TSFlags & ARMII::DomainMask;
376513fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
376613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  if (Domain & ARMII::DomainNEON)
37678bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen    return std::make_pair(ExeNEON, 0);
376813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
376913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  // Certain instructions can go either way on Cortex-A8.
377013fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  // Treat them as NEON instructions.
377113fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8())
37728bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen    return std::make_pair(ExeNEON, 0);
377313fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
377413fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  if (Domain & ARMII::DomainVFP)
37758bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen    return std::make_pair(ExeVFP, 0);
377613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
37778bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen  return std::make_pair(ExeGeneric, 0);
377813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen}
377913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
378020599ea4bced03634a54b52e98d261018366f279Tim Northoverstatic unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI,
378120599ea4bced03634a54b52e98d261018366f279Tim Northover                                            unsigned SReg, unsigned &Lane) {
378220599ea4bced03634a54b52e98d261018366f279Tim Northover  unsigned DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_0, &ARM::DPRRegClass);
378320599ea4bced03634a54b52e98d261018366f279Tim Northover  Lane = 0;
378420599ea4bced03634a54b52e98d261018366f279Tim Northover
378520599ea4bced03634a54b52e98d261018366f279Tim Northover  if (DReg != ARM::NoRegister)
378620599ea4bced03634a54b52e98d261018366f279Tim Northover   return DReg;
378720599ea4bced03634a54b52e98d261018366f279Tim Northover
378820599ea4bced03634a54b52e98d261018366f279Tim Northover  Lane = 1;
378920599ea4bced03634a54b52e98d261018366f279Tim Northover  DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1, &ARM::DPRRegClass);
379020599ea4bced03634a54b52e98d261018366f279Tim Northover
379120599ea4bced03634a54b52e98d261018366f279Tim Northover  assert(DReg && "S-register with no D super-register?");
379220599ea4bced03634a54b52e98d261018366f279Tim Northover  return DReg;
379320599ea4bced03634a54b52e98d261018366f279Tim Northover}
379420599ea4bced03634a54b52e98d261018366f279Tim Northover
37952d15d641aa8aa9e48c268170f1a9825bb9926fc7Andrew Trick/// getImplicitSPRUseForDPRUse - Given a use of a DPR register and lane,
379697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// set ImplicitSReg to a register number that must be marked as implicit-use or
379797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// zero if no register needs to be defined as implicit-use.
379897ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy///
379997ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// If the function cannot determine if an SPR should be marked implicit use or
380097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// not, it returns false.
380197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy///
380297ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// This function handles cases where an instruction is being modified from taking
38032d15d641aa8aa9e48c268170f1a9825bb9926fc7Andrew Trick/// an SPR to a DPR[Lane]. A use of the DPR is being added, which may conflict
380497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// with an earlier def of an SPR corresponding to DPR[Lane^1] (i.e. the other
380597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// lane of the DPR).
380697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy///
380797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// If the other SPR is defined, an implicit-use of it should be added. Else,
380897ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy/// (including the case where the DPR itself is defined), it should not.
38092d15d641aa8aa9e48c268170f1a9825bb9926fc7Andrew Trick///
381097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloystatic bool getImplicitSPRUseForDPRUse(const TargetRegisterInfo *TRI,
381197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy                                       MachineInstr *MI,
381297ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy                                       unsigned DReg, unsigned Lane,
381397ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy                                       unsigned &ImplicitSReg) {
381497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  // If the DPR is defined or used already, the other SPR lane will be chained
381597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  // correctly, so there is nothing to be done.
381697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  if (MI->definesRegister(DReg, TRI) || MI->readsRegister(DReg, TRI)) {
381797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    ImplicitSReg = 0;
381897ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    return true;
381997ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  }
382097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy
382197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  // Otherwise we need to go searching to see if the SPR is set explicitly.
382297ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  ImplicitSReg = TRI->getSubReg(DReg,
382397ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy                                (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
382497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  MachineBasicBlock::LivenessQueryResult LQR =
382597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    MI->getParent()->computeRegisterLiveness(TRI, ImplicitSReg, MI);
382697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy
382797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  if (LQR == MachineBasicBlock::LQR_Live)
382897ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    return true;
382997ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  else if (LQR == MachineBasicBlock::LQR_Unknown)
383097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    return false;
383197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy
383297ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  // If the register is known not to be live, there is no need to add an
383397ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  // implicit-use.
383497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  ImplicitSReg = 0;
383597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy  return true;
383697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy}
383720599ea4bced03634a54b52e98d261018366f279Tim Northover
383813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesenvoid
383913fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund OlesenARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
38403c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  unsigned DstReg, SrcReg, DReg;
38413c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  unsigned Lane;
384237a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
38433c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  const TargetRegisterInfo *TRI = &getRegisterInfo();
38443c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  switch (MI->getOpcode()) {
38453c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover    default:
38463c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      llvm_unreachable("cannot handle opcode!");
38473c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      break;
38483c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover    case ARM::VMOVD:
38493c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      if (Domain != ExeNEON)
38503c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover        break;
38513c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
38523c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      // Zap the predicate operands.
38533c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      assert(!isPredicated(MI) && "Cannot predicate a VORRd");
38543c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
385520599ea4bced03634a54b52e98d261018366f279Tim Northover      // Source instruction is %DDst = VMOVD %DSrc, 14, %noreg (; implicits)
385620599ea4bced03634a54b52e98d261018366f279Tim Northover      DstReg = MI->getOperand(0).getReg();
385720599ea4bced03634a54b52e98d261018366f279Tim Northover      SrcReg = MI->getOperand(1).getReg();
38583c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
385920599ea4bced03634a54b52e98d261018366f279Tim Northover      for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
386020599ea4bced03634a54b52e98d261018366f279Tim Northover        MI->RemoveOperand(i-1);
386120599ea4bced03634a54b52e98d261018366f279Tim Northover
386220599ea4bced03634a54b52e98d261018366f279Tim Northover      // Change to a %DDst = VORRd %DSrc, %DSrc, 14, %noreg (; implicits)
386320599ea4bced03634a54b52e98d261018366f279Tim Northover      MI->setDesc(get(ARM::VORRd));
386420599ea4bced03634a54b52e98d261018366f279Tim Northover      AddDefaultPred(MIB.addReg(DstReg, RegState::Define)
386520599ea4bced03634a54b52e98d261018366f279Tim Northover                        .addReg(SrcReg)
386620599ea4bced03634a54b52e98d261018366f279Tim Northover                        .addReg(SrcReg));
38673c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      break;
38683c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover    case ARM::VMOVRS:
38693c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      if (Domain != ExeNEON)
38703c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover        break;
38713c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      assert(!isPredicated(MI) && "Cannot predicate a VGETLN");
38723c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
387320599ea4bced03634a54b52e98d261018366f279Tim Northover      // Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits)
38743c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      DstReg = MI->getOperand(0).getReg();
38753c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      SrcReg = MI->getOperand(1).getReg();
387613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
387720599ea4bced03634a54b52e98d261018366f279Tim Northover      for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
387820599ea4bced03634a54b52e98d261018366f279Tim Northover        MI->RemoveOperand(i-1);
38793c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
388020599ea4bced03634a54b52e98d261018366f279Tim Northover      DReg = getCorrespondingDRegAndLane(TRI, SrcReg, Lane);
38813c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
388220599ea4bced03634a54b52e98d261018366f279Tim Northover      // Convert to %RDst = VGETLNi32 %DSrc, Lane, 14, %noreg (; imps)
388320599ea4bced03634a54b52e98d261018366f279Tim Northover      // Note that DSrc has been widened and the other lane may be undef, which
388420599ea4bced03634a54b52e98d261018366f279Tim Northover      // contaminates the entire register.
38853c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      MI->setDesc(get(ARM::VGETLNi32));
388620599ea4bced03634a54b52e98d261018366f279Tim Northover      AddDefaultPred(MIB.addReg(DstReg, RegState::Define)
388720599ea4bced03634a54b52e98d261018366f279Tim Northover                        .addReg(DReg, RegState::Undef)
388820599ea4bced03634a54b52e98d261018366f279Tim Northover                        .addImm(Lane));
38893c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
389020599ea4bced03634a54b52e98d261018366f279Tim Northover      // The old source should be an implicit use, otherwise we might think it
389120599ea4bced03634a54b52e98d261018366f279Tim Northover      // was dead before here.
38923c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      MIB.addReg(SrcReg, RegState::Implicit);
38933c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      break;
389497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    case ARM::VMOVSR: {
38953c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      if (Domain != ExeNEON)
38963c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover        break;
38973c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      assert(!isPredicated(MI) && "Cannot predicate a VSETLN");
38983c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
389920599ea4bced03634a54b52e98d261018366f279Tim Northover      // Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits)
39003c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      DstReg = MI->getOperand(0).getReg();
39013c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      SrcReg = MI->getOperand(1).getReg();
39023c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
390320599ea4bced03634a54b52e98d261018366f279Tim Northover      DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane);
39043c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover
390597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      unsigned ImplicitSReg;
390697ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      if (!getImplicitSPRUseForDPRUse(TRI, MI, DReg, Lane, ImplicitSReg))
390797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy        break;
390889f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
39097bebddf55ece46995f310d79195afb4e5b239886Tim Northover      for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
39107bebddf55ece46995f310d79195afb4e5b239886Tim Northover        MI->RemoveOperand(i-1);
39117bebddf55ece46995f310d79195afb4e5b239886Tim Northover
391220599ea4bced03634a54b52e98d261018366f279Tim Northover      // Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps)
391320599ea4bced03634a54b52e98d261018366f279Tim Northover      // Again DDst may be undefined at the beginning of this instruction.
391420599ea4bced03634a54b52e98d261018366f279Tim Northover      MI->setDesc(get(ARM::VSETLNi32));
391589f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      MIB.addReg(DReg, RegState::Define)
391689f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover         .addReg(DReg, getUndefRegState(!MI->readsRegister(DReg, TRI)))
391789f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover         .addReg(SrcReg)
391889f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover         .addImm(Lane);
391989f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      AddDefaultPred(MIB);
3920c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
392189f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // The narrower destination must be marked as set to keep previous chains
392289f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // in place.
392320599ea4bced03634a54b52e98d261018366f279Tim Northover      MIB.addReg(DstReg, RegState::Define | RegState::Implicit);
392497ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      if (ImplicitSReg != 0)
392597ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy        MIB.addReg(ImplicitSReg, RegState::Implicit);
39263c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover      break;
392797ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy    }
3928c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover    case ARM::VMOVS: {
3929c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      if (Domain != ExeNEON)
3930c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        break;
3931c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3932c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // Source instruction is %SDst = VMOVS %SSrc, 14, %noreg (; implicits)
3933c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      DstReg = MI->getOperand(0).getReg();
3934c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      SrcReg = MI->getOperand(1).getReg();
3935c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3936c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      unsigned DstLane = 0, SrcLane = 0, DDst, DSrc;
3937c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      DDst = getCorrespondingDRegAndLane(TRI, DstReg, DstLane);
3938c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      DSrc = getCorrespondingDRegAndLane(TRI, SrcReg, SrcLane);
3939c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
394097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      unsigned ImplicitSReg;
394197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      if (!getImplicitSPRUseForDPRUse(TRI, MI, DSrc, SrcLane, ImplicitSReg))
394297ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy        break;
394389f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
39447bebddf55ece46995f310d79195afb4e5b239886Tim Northover      for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
39457bebddf55ece46995f310d79195afb4e5b239886Tim Northover        MI->RemoveOperand(i-1);
39467bebddf55ece46995f310d79195afb4e5b239886Tim Northover
3947c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      if (DSrc == DDst) {
3948c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        // Destination can be:
3949c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        //     %DDst = VDUPLN32d %DDst, Lane, 14, %noreg (; implicits)
3950c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        MI->setDesc(get(ARM::VDUPLN32d));
395189f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover        MIB.addReg(DDst, RegState::Define)
395289f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover           .addReg(DDst, getUndefRegState(!MI->readsRegister(DDst, TRI)))
395389f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover           .addImm(SrcLane);
395489f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover        AddDefaultPred(MIB);
3955c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3956c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        // Neither the source or the destination are naturally represented any
3957c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        // more, so add them in manually.
3958c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        MIB.addReg(DstReg, RegState::Implicit | RegState::Define);
3959c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        MIB.addReg(SrcReg, RegState::Implicit);
396097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy        if (ImplicitSReg != 0)
396197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy          MIB.addReg(ImplicitSReg, RegState::Implicit);
3962c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        break;
3963c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      }
3964c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3965c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // In general there's no single instruction that can perform an S <-> S
3966c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // move in NEON space, but a pair of VEXT instructions *can* do the
3967c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // job. It turns out that the VEXTs needed will only use DSrc once, with
3968c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // the position based purely on the combination of lane-0 and lane-1
3969c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // involved. For example
3970c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //     vmov s0, s2 -> vext.32 d0, d0, d1, #1  vext.32 d0, d0, d0, #1
3971c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //     vmov s1, s3 -> vext.32 d0, d1, d0, #1  vext.32 d0, d0, d0, #1
3972c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //     vmov s0, s3 -> vext.32 d0, d0, d0, #1  vext.32 d0, d1, d0, #1
3973c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //     vmov s1, s2 -> vext.32 d0, d0, d0, #1  vext.32 d0, d0, d1, #1
3974c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //
3975c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // Pattern of the MachineInstrs is:
3976c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      //     %DDst = VEXTd32 %DSrc1, %DSrc2, Lane, 14, %noreg (;implicits)
3977c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      MachineInstrBuilder NewMIB;
3978c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      NewMIB = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
3979c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover                       get(ARM::VEXTd32), DDst);
398089f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
398189f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // On the first instruction, both DSrc and DDst may be <undef> if present.
398289f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // Specifically when the original instruction didn't have them as an
398389f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // <imp-use>.
398489f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
398589f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      bool CurUndef = !MI->readsRegister(CurReg, TRI);
398689f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      NewMIB.addReg(CurReg, getUndefRegState(CurUndef));
398789f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
398889f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
398989f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurUndef = !MI->readsRegister(CurReg, TRI);
399089f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      NewMIB.addReg(CurReg, getUndefRegState(CurUndef));
399189f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
3992c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      NewMIB.addImm(1);
3993c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      AddDefaultPred(NewMIB);
3994c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3995c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      if (SrcLane == DstLane)
3996c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        NewMIB.addReg(SrcReg, RegState::Implicit);
3997c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
3998c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      MI->setDesc(get(ARM::VEXTd32));
3999c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      MIB.addReg(DDst, RegState::Define);
400089f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
400189f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // On the second instruction, DDst has definitely been defined above, so
400289f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      // it is not <undef>. DSrc, if present, can be <undef> as above.
400389f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
400489f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurUndef = CurReg == DSrc && !MI->readsRegister(CurReg, TRI);
400589f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      MIB.addReg(CurReg, getUndefRegState(CurUndef));
400689f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
400789f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
400889f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      CurUndef = CurReg == DSrc && !MI->readsRegister(CurReg, TRI);
400989f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover      MIB.addReg(CurReg, getUndefRegState(CurUndef));
401089f49808ee79eebbc3267b6c595514d4ca1f3247Tim Northover
4011c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      MIB.addImm(1);
4012c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      AddDefaultPred(MIB);
4013c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
4014c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      if (SrcLane != DstLane)
4015c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover        MIB.addReg(SrcReg, RegState::Implicit);
4016c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover
4017c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // As before, the original destination is no longer represented, add it
4018c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      // implicitly.
4019c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      MIB.addReg(DstReg, RegState::Define | RegState::Implicit);
402097ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy      if (ImplicitSReg != 0)
402197ecb83dffb5ff78ff84e9da21189268f52c63b2James Molloy        MIB.addReg(ImplicitSReg, RegState::Implicit);
4022c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover      break;
4023c4a32e6596f3974a6c00322db1f5f31ea448bd58Tim Northover    }
40243c8ad92455ff06c8e69085702ef1f13944eab4ddTim Northover  }
40258bb3d3cb30df06bdcb3ef5a208e3e59f4eeb4868Jakob Stoklund Olesen
402613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen}
4027c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach
4028eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//===----------------------------------------------------------------------===//
4029eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// Partial register updates
4030eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//===----------------------------------------------------------------------===//
4031eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//
4032eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// Swift renames NEON registers with 64-bit granularity.  That means any
4033eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// instruction writing an S-reg implicitly reads the containing D-reg.  The
4034eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// problem is mostly avoided by translating f32 operations to v2f32 operations
4035eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// on D-registers, but f32 loads are still a problem.
4036eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//
4037eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// These instructions can load an f32 into a NEON register:
4038eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//
4039eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// VLDRS - Only writes S, partial D update.
4040eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// VLD1LNd32 - Writes all D-regs, explicit partial D update, 2 uops.
4041eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// VLD1DUPd32 - Writes all D-regs, no partial reg update, 2 uops.
4042eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson//
4043eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// FCONSTD can be used as a dependency-breaking instruction.
4044eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilsonunsigned ARMBaseInstrInfo::
4045eb1641d54a7eda7717304bc4d55d059208d8ebedBob WilsongetPartialRegUpdateClearance(const MachineInstr *MI,
4046eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                             unsigned OpNum,
4047eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                             const TargetRegisterInfo *TRI) const {
4048a210db781f17b5ab8e2b71d53276153a9d15eeadSilviu Baranga  if (!SwiftPartialUpdateClearance ||
4049a210db781f17b5ab8e2b71d53276153a9d15eeadSilviu Baranga      !(Subtarget.isSwift() || Subtarget.isCortexA15()))
4050eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 0;
4051eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4052eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(TRI && "Need TRI instance");
4053eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4054eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
4055eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  if (MO.readsReg())
4056eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 0;
4057eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  unsigned Reg = MO.getReg();
4058eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  int UseOp = -1;
4059eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4060eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  switch(MI->getOpcode()) {
4061eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // Normal instructions writing only an S-register.
4062eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VLDRS:
4063eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::FCONSTS:
4064eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVSR:
4065eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVv8i8:
4066eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVv4i16:
4067eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVv2i32:
4068eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVv2f32:
4069eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VMOVv1i64:
4070eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    UseOp = MI->findRegisterUseOperandIdx(Reg, false, TRI);
4071eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    break;
4072eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4073eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // Explicitly reads the dependency.
4074eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  case ARM::VLD1LNd32:
4075a210db781f17b5ab8e2b71d53276153a9d15eeadSilviu Baranga    UseOp = 3;
4076eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    break;
4077eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  default:
4078eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 0;
4079eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
4080eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4081eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // If this instruction actually reads a value from Reg, there is no unwanted
4082eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // dependency.
4083eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  if (UseOp != -1 && MI->getOperand(UseOp).readsReg())
4084eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    return 0;
4085eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4086eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // We must be able to clobber the whole D-reg.
4087eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  if (TargetRegisterInfo::isVirtualRegister(Reg)) {
4088eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // Virtual register must be a foo:ssub_0<def,undef> operand.
4089eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!MO.getSubReg() || MI->readsVirtualRegister(Reg))
4090eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 0;
4091eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  } else if (ARM::SPRRegClass.contains(Reg)) {
4092eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    // Physical register: MI must define the full D-reg.
4093eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    unsigned DReg = TRI->getMatchingSuperReg(Reg, ARM::ssub_0,
4094eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                                             &ARM::DPRRegClass);
4095eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    if (!DReg || !MI->definesRegister(DReg, TRI))
4096eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson      return 0;
4097eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
4098eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4099eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // MI has an unwanted D-register dependency.
4100eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // Avoid defs in the previous N instructrions.
4101eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  return SwiftPartialUpdateClearance;
4102eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson}
4103eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4104eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// Break a partial register dependency after getPartialRegUpdateClearance
4105eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson// returned non-zero.
4106eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilsonvoid ARMBaseInstrInfo::
4107eb1641d54a7eda7717304bc4d55d059208d8ebedBob WilsonbreakPartialRegDependency(MachineBasicBlock::iterator MI,
4108eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                          unsigned OpNum,
4109eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                          const TargetRegisterInfo *TRI) const {
4110eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(MI && OpNum < MI->getDesc().getNumDefs() && "OpNum is not a def");
4111eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(TRI && "Need TRI instance");
4112eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4113eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
4114eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  unsigned Reg = MO.getReg();
4115eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
4116eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson         "Can't break virtual register dependencies.");
4117eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  unsigned DReg = Reg;
4118eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4119eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // If MI defines an S-reg, find the corresponding D super-register.
4120eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  if (ARM::SPRRegClass.contains(Reg)) {
4121eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    DReg = ARM::D0 + (Reg - ARM::S0) / 2;
4122eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson    assert(TRI->isSuperRegister(Reg, DReg) && "Register enums broken");
4123eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  }
4124eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4125eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(ARM::DPRRegClass.contains(DReg) && "Can only break D-reg deps");
4126eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  assert(MI->definesRegister(DReg, TRI) && "MI doesn't clobber full D-reg");
4127eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4128eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // FIXME: In some cases, VLDRS can be changed to a VLD1DUPd32 which defines
4129eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // the full D-register by loading the same value to both lanes.  The
4130eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // instruction is micro-coded with 2 uops, so don't do this until we can
4131eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // properly schedule micro-coded instuctions.  The dispatcher stalls cause
4132eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // too big regressions.
4133eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4134eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // Insert the dependency-breaking FCONSTD before MI.
4135eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  // 96 is the encoding of 0.5, but the actual value doesn't matter here.
4136eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  AddDefaultPred(BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
4137eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson                         get(ARM::FCONSTD), DReg).addImm(96));
4138eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson  MI->addRegisterKilled(DReg, TRI, true);
4139eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson}
4140eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson
4141c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbachbool ARMBaseInstrInfo::hasNOP() const {
4142c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach  return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
4143c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach}
414408da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer
414508da4865576056f997a9c8013240d716018f7edfArnold Schwaighoferbool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
4146d87bd5627e5b78cb556d6c7b5aa76ae3d55d8acfArnold Schwaighofer  if (MI->getNumOperands() < 4)
4147d87bd5627e5b78cb556d6c7b5aa76ae3d55d8acfArnold Schwaighofer    return true;
414808da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer  unsigned ShOpVal = MI->getOperand(3).getImm();
414908da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer  unsigned ShImm = ARM_AM::getSORegOffset(ShOpVal);
415008da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer  // Swift supports faster shifts for: lsl 2, lsl 1, and lsr 1.
415108da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer  if ((ShImm == 1 && ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsr) ||
415208da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer      ((ShImm == 1 || ShImm == 2) &&
415308da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer       ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsl))
415408da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer    return true;
415508da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer
415608da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer  return false;
415708da4865576056f997a9c8013240d716018f7edfArnold Schwaighofer}
4158