ARMBaseInstrInfo.cpp revision f967ca0eaf30325cabe3c1971bf0dba16cf1b027
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===- ARMBaseInstrInfo.cpp - ARM Instruction Information -------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file contains the Base ARM implementation of the TargetInstrInfo class.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "ARMBaseInstrInfo.h"
150979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor#include "ARM.h"
16a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner#include "ARMAddressingModes.h"
172eadfb638eb1bb6ccfd6fd0453e764d47e27eed9Chris Lattner#include "ARMConstantPoolValue.h"
18a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner#include "ARMGenInstrInfo.inc"
1998cd599ee8a9b259ed7388ee2921a20d97658864Douglas Gregor#include "ARMMachineFunctionInfo.h"
20aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#include "ARMRegisterInfo.h"
2119cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "llvm/Constants.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Function.h"
2308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "llvm/GlobalValue.h"
2408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "llvm/ADT/STLExtras.h"
257a614d8380297fcd2bc23986241905d97222948cRichard Smith#include "llvm/CodeGen/LiveVariables.h"
261b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "llvm/CodeGen/MachineConstantPool.h"
2708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h"
28da5a6b6d9fd52899499d5b7b46273ec844dcaa6eChris Lattner#include "llvm/CodeGen/MachineInstrBuilder.h"
29cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor#include "llvm/CodeGen/MachineJumpTableInfo.h"
303a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson#include "llvm/CodeGen/MachineMemOperand.h"
31ffb4b6e299069139908540ce97be4462e16b53a4Douglas Gregor#include "llvm/CodeGen/MachineRegisterInfo.h"
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/CodeGen/PseudoSourceValue.h"
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/MC/MCAsmInfo.h"
342b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner#include "llvm/Support/CommandLine.h"
352b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner#include "llvm/Support/Debug.h"
362b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner#include "llvm/Support/ErrorHandling.h"
372b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattnerusing namespace llvm;
382b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
39f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbournestatic cl::opt<bool>
40f111d935722ed488144600cea5ed03a6b5069e8fPeter CollingbourneEnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
412b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner               cl::desc("Enable ARM 2-addr to 3-addr conv"));
42f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne
43c302113179a1c2b1254224ea9b6f5316ceeb375cSean HuntARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI)
44f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
45c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    Subtarget(STI) {
46f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne}
472b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
482de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallMachineInstr *
492b334bb3126a67895813e49e6228dad4aec0b4d6Chris LattnerARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
502b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                        MachineBasicBlock::iterator &MBBI,
512b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                        LiveVariables *LV) const {
522b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  // FIXME: Thumb2 support.
532b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
54c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  if (!EnableARM3Addr)
556907fbe758d23e1aec4c0a67e7b633d1d855feb4John McCall    return NULL;
566907fbe758d23e1aec4c0a67e7b633d1d855feb4John McCall
57f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  MachineInstr *MI = MBBI;
582b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  MachineFunction &MF = *MI->getParent()->getParent();
59c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  uint64_t TSFlags = MI->getDesc().TSFlags;
60f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  bool isPre = false;
612b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
622b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  default: return NULL;
632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARMII::IndexModePre:
642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    isPre = true;
652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    break;
662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARMII::IndexModePost:
672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    break;
682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // Try splitting an indexed load/store to an un-indexed one plus an add/sub
712b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  // operation.
72c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (MemOpc == 0)
742de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    return NULL;
752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
762b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  MachineInstr *UpdateMI = NULL;
772b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  MachineInstr *MemMI = NULL;
782b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
79c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  const TargetInstrDesc &TID = MI->getDesc();
802de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  unsigned NumOps = TID.getNumOperands();
812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  bool isLoad = !TID.mayStore();
822b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
832b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  const MachineOperand &Base = MI->getOperand(2);
842b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  const MachineOperand &Offset = MI->getOperand(NumOps-3);
85c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  unsigned WBReg = WB.getReg();
86f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  unsigned BaseReg = Base.getReg();
872b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  unsigned OffReg = Offset.getReg();
882b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  unsigned OffImm = MI->getOperand(NumOps-2).getImm();
89c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
902b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  switch (AddrMode) {
912b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  default:
922b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    assert(false && "Unknown indexed op!");
9363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    return NULL;
9463c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  case ARMII::AddrMode2: {
9563c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
9663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    unsigned Amt = ARM_AM::getAM2Offset(OffImm);
9763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    if (OffReg == 0) {
9863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      if (ARM_AM::getSOImmVal(Amt) == -1)
9963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        // Can't encode it in a so_imm operand. This transformation will
10063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        // add more than 1 instruction. Abandon!
10163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        return NULL;
10263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
10363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                         get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
10463c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addReg(BaseReg).addImm(Amt)
10563c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addImm(Pred).addReg(0).addReg(0);
10663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    } else if (Amt != 0) {
10763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
10863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
10963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
11063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                         get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
11163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
11263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addImm(Pred).addReg(0).addReg(0);
11363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    } else
11463c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
11563c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                         get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
11663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addReg(BaseReg).addReg(OffReg)
11763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addImm(Pred).addReg(0).addReg(0);
11863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    break;
11963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  }
12063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  case ARMII::AddrMode3 : {
12163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
12263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    unsigned Amt = ARM_AM::getAM3Offset(OffImm);
12363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    if (OffReg == 0)
12463c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
12563c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
12663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                         get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
12763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addReg(BaseReg).addImm(Amt)
12863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        .addImm(Pred).addReg(0).addReg(0);
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        .addReg(BaseReg).addReg(OffReg)
133561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        .addImm(Pred).addReg(0).addReg(0);
134561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    break;
135d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  }
136d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  }
137d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor
138561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  std::vector<MachineInstr*> NewMIs;
139561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  if (isPre) {
140d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    if (isLoad)
141d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor      MemMI = BuildMI(MF, MI->getDebugLoc(),
142561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                      get(MemOpc), MI->getOperand(0).getReg())
1430da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor        .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
1440da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    else
1450da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      MemMI = BuildMI(MF, MI->getDebugLoc(),
1460da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
147c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt        .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
1480da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    NewMIs.push_back(MemMI);
1490da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    NewMIs.push_back(UpdateMI);
1500da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  } else {
151d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    if (isLoad)
1520da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      MemMI = BuildMI(MF, MI->getDebugLoc(),
1530da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                      get(MemOpc), MI->getOperand(0).getReg())
154d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor        .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
155d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    else
156d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor      MemMI = BuildMI(MF, MI->getDebugLoc(),
157561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
158d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor        .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
159561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    if (WB.isDead())
160561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      UpdateMI->getOperand(0).setIsDead();
1610da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    NewMIs.push_back(UpdateMI);
162d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    NewMIs.push_back(MemMI);
1630da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  }
164d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor
165561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  // Transfer LiveVariables states, kill / dead info.
166561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  if (LV) {
167561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
168561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      MachineOperand &MO = MI->getOperand(i);
169561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      if (MO.isReg() && MO.getReg() &&
170561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor          TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
171561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        unsigned Reg = MO.getReg();
172561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
173561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
174561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        if (MO.isDef()) {
175561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor          MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
1760da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor          if (MO.isDead())
177561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor            LV->addVirtualRegisterDead(Reg, NewMI);
1780da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor        }
179d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor        if (MO.isUse() && MO.isKill()) {
180d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor          for (unsigned j = 0; j < 2; ++j) {
181561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor            // Look at the two new MI's in reverse order.
182d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor            MachineInstr *NewMI = NewMIs[j];
183d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor            if (!NewMI->readsRegister(Reg))
184d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor              continue;
1850da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor            LV->addVirtualRegisterKilled(Reg, NewMI);
1860da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor            if (VI.removeKill(MI))
187d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor              VI.Kills.push_back(NewMI);
1882ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor            break;
189501edb6a54524555ad27fbf41a7920dc756b08c6Douglas Gregor          }
19031310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl        }
191561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      }
192d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    }
193561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
194561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
195bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  MFI->insert(MBBI, NewMIs[1]);
196d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  MFI->insert(MBBI, NewMIs[0]);
197bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  return NewMIs[0];
198bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor}
199bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor
200bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregorbool
201561f81243f665cf2001caadc45df505f826b72d6Douglas GregorARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
202d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor                                        MachineBasicBlock::iterator MI,
203561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                                        const std::vector<CalleeSavedInfo> &CSI,
204561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                                        const TargetRegisterInfo *TRI) const {
205d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  if (CSI.empty())
206d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    return false;
207d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor
208d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  DebugLoc DL;
209bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  if (MI != MBB.end()) DL = MI->getDebugLoc();
210bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor
211bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
212d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    unsigned Reg = CSI[i].getReg();
213d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    bool isKill = true;
214561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
215d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    // Add the callee-saved register as live-in unless it's LR and
216d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
217d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    // then it's already added to the function and entry block live-in sets.
218d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    if (Reg == ARM::LR) {
219d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor      MachineFunction &MF = *MBB.getParent();
220d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor      if (MF.getFrameInfo()->isReturnAddressTaken() &&
221d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor          MF.getRegInfo().isLiveIn(Reg))
222561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        isKill = false;
223561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    }
224561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
225d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    if (isKill)
226d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor      MBB.addLiveIn(Reg);
227d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor
228d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    // Insert the spill to the stack frame. The register is killed at the spill
229d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    //
230d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
231d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    storeRegToStackSlot(MBB, MI, Reg, isKill,
232d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor                        CSI[i].getFrameIdx(), RC, TRI);
233d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  }
234d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  return true;
235d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor}
236d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor
237561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor// Branch analysis.
238561f81243f665cf2001caadc45df505f826b72d6Douglas Gregorbool
239d967e31ee796efff24b84b704a063634f6b55627Douglas GregorARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
240d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor                                MachineBasicBlock *&FBB,
241561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                                SmallVectorImpl<MachineOperand> &Cond,
242d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor                                bool AllowModify) const {
243d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  // If the block has no terminators, it just falls into the block after it.
244d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  MachineBasicBlock::iterator I = MBB.end();
245d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  if (I == MBB.begin())
246561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    return false;
247d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor  --I;
24810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  while (I->isDebugValue()) {
249d967e31ee796efff24b84b704a063634f6b55627Douglas Gregor    if (I == MBB.begin())
2501fe85ea697fb5c85acded3ac0ddbc19f89c2e181Douglas Gregor      return false;
2510da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    --I;
2520da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  }
2533aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  if (!isUnpredicatedTerminator(I))
2542577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    return false;
2553aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
2562577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  // Get the last instruction in the block.
257f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  MachineInstr *LastInst = I;
258561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
259cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth  // If there is only one terminator instruction, process it.
260cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth  unsigned LastOpc = LastInst->getOpcode();
2617e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
2626857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth    if (isUncondBranchOpcode(LastOpc)) {
2633aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      TBB = LastInst->getOperand(0).getMBB();
2643aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      return false;
2653aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    }
266cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    if (isCondBranchOpcode(LastOpc)) {
267561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      // Block ends with fall-through condbranch.
268561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      TBB = LastInst->getOperand(0).getMBB();
269561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      Cond.push_back(LastInst->getOperand(1));
270561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      Cond.push_back(LastInst->getOperand(2));
271561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      return false;
272561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    }
273561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    return true;  // Can't handle indirect branch.
274561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
275561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
276561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  // Get the instruction before it if it is a terminator.
277561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  MachineInstr *SecondLastInst = I;
2782577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
2792577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  // If there are three terminators, we don't know what sort of block this is.
2802577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
281a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    return true;
28240d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor
283dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall  // If the block ends with a B and a Bcc, handle it.
284a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  unsigned SecondLastOpc = SecondLastInst->getOpcode();
2850da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
286f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    TBB =  SecondLastInst->getOperand(0).getMBB();
2873aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    Cond.push_back(SecondLastInst->getOperand(1));
2880da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    Cond.push_back(SecondLastInst->getOperand(2));
28940d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor    FBB = LastInst->getOperand(0).getMBB();
2902577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    return false;
2913aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  }
2922577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
2932577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  // If the block ends with two unconditional branches, handle it.  The second
2942577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  // one is not executed, so remove it.
29540d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor  if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
2962577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    TBB = SecondLastInst->getOperand(0).getMBB();
2972577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    I = LastInst;
2982577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    if (AllowModify)
299f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      I->eraseFromParent();
3003aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    return false;
3012577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  }
3023aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
3033aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  // ...likewise if it ends with a branch table followed by an unconditional
3043aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  // branch. The branch folder can create these, and we must get rid of them for
3053aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  // correctness of Thumb constant islands.
306a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  if ((isJumpTableBranchOpcode(SecondLastOpc) ||
30740d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor       isIndirectBranchOpcode(SecondLastOpc)) &&
3086857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      isUncondBranchOpcode(LastOpc)) {
3093aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    I = LastInst;
3103aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    if (AllowModify)
311d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      I->eraseFromParent();
312b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis    return true;
3133aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  }
3143248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner
3153aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  // Otherwise, can't handle this.
3163aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  return true;
317a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor}
318a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
3193aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
320def0354384d9c4431f7b58b664b59896d4623028Douglas Gregorunsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
3213aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  MachineBasicBlock::iterator I = MBB.end();
322def0354384d9c4431f7b58b664b59896d4623028Douglas Gregor  if (I == MBB.begin()) return 0;
323663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  --I;
324663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  while (I->isDebugValue()) {
325663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis    if (I == MBB.begin())
3266857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      return 0;
3273aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    --I;
3283aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth  }
329def0354384d9c4431f7b58b664b59896d4623028Douglas Gregor  if (!isUncondBranchOpcode(I->getOpcode()) &&
330b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis      !isCondBranchOpcode(I->getOpcode()))
3313aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    return 0;
3323248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner
333663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  // Remove the branch.
334663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  I->eraseFromParent();
335663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis
336a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  I = MBB.end();
3372577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
338a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  if (I == MBB.begin()) return 1;
33940d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor  --I;
340096832c5ed5b9106fa177ebc148489760c3bc496John McCall  if (!isCondBranchOpcode(I->getOpcode()))
341a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    return 1;
342a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
343a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // Remove the branch.
344a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  I->eraseFromParent();
3453a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return 2;
3463a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
347848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson
348848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlssonunsigned
349848fa64143fbe5ae62a601ad61277f741e54dfabAnders CarlssonARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
3503a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                               MachineBasicBlock *FBB,
351848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson                               const SmallVectorImpl<MachineOperand> &Cond,
3523a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                               DebugLoc DL) const {
3533a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
3543a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  int BOpc   = !AFI->isThumbFunction()
3553a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB);
3563a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  int BccOpc = !AFI->isThumbFunction()
3573a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc);
358848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson
3593a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Shouldn't be a fall through.
3604eadcc569223135e13353c9381b448986e3f7053Sam Weinig  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
3614eadcc569223135e13353c9381b448986e3f7053Sam Weinig  assert((Cond.size() == 2 || Cond.size() == 0) &&
3623a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson         "ARM branch conditions have two components!");
3633a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3643a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  if (FBB == 0) {
3653a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    if (Cond.empty()) // Unconditional branch?
3663a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson      BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
3673a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    else
368183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall      BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
3693a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
3703a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return 1;
3713a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  }
3723a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3733a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Two-way conditional branch.
3743a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
3753a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
3763a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
3773a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return 2;
3783a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
3793a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3803a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlssonbool ARMBaseInstrInfo::
3813a082d81006e7a2e01a6e431a22e21c78490ff8fAnders CarlssonReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
3823a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
3833a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
3843a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return false;
3853a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
3863a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3873a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlssonbool ARMBaseInstrInfo::
3883a082d81006e7a2e01a6e431a22e21c78490ff8fAnders CarlssonPredicateInstruction(MachineInstr *MI,
3893a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                     const SmallVectorImpl<MachineOperand> &Pred) const {
3904eadcc569223135e13353c9381b448986e3f7053Sam Weinig  unsigned Opc = MI->getOpcode();
3914eadcc569223135e13353c9381b448986e3f7053Sam Weinig  if (isUncondBranchOpcode(Opc)) {
3924eadcc569223135e13353c9381b448986e3f7053Sam Weinig    MI->setDesc(get(getMatchingCondBranchOpcode(Opc)));
3934eadcc569223135e13353c9381b448986e3f7053Sam Weinig    MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
3944eadcc569223135e13353c9381b448986e3f7053Sam Weinig    MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false));
3954eadcc569223135e13353c9381b448986e3f7053Sam Weinig    return true;
3964eadcc569223135e13353c9381b448986e3f7053Sam Weinig  }
3974eadcc569223135e13353c9381b448986e3f7053Sam Weinig
3983a1ce1ed0f5686384e712837bad28c576622e442Sam Weinig  int PIdx = MI->findFirstPredOperandIdx();
3993a1ce1ed0f5686384e712837bad28c576622e442Sam Weinig  if (PIdx != -1) {
4003a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    MachineOperand &PMO = MI->getOperand(PIdx);
4013a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    PMO.setImm(Pred[0].getImm());
4023a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
4033a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return true;
4043a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  }
4053a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return false;
4063a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
4073a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
4083a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlssonbool ARMBaseInstrInfo::
4093a082d81006e7a2e01a6e431a22e21c78490ff8fAnders CarlssonSubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
4103a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                  const SmallVectorImpl<MachineOperand> &Pred2) const {
411b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek  if (Pred1.size() > 2 || Pred2.size() > 2)
412b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek    return false;
413b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek
414b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek  ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
415900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer  ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
416b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek  if (CC1 == CC2)
4173a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return true;
418900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer
419900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer  switch (CC1) {
420900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer  default:
4213a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return false;
4223a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  case ARMCC::AL:
4233a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return true;
4243a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  case ARMCC::HS:
4253a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return CC2 == ARMCC::HI;
4263a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  case ARMCC::LS:
4273a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
4283a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  case ARMCC::GE:
4293a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return CC2 == ARMCC::GT;
4303a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  case ARMCC::LE:
4313a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    return CC2 == ARMCC::LT;
4323a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  }
4333a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
4343a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
4359996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidisbool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
4369996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                    std::vector<MachineOperand> &Pred) const {
4379996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // FIXME: This confuses implicit_def with optional CPSR def.
4389996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  const TargetInstrDesc &TID = MI->getDesc();
4399996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
4409996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return false;
4419996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4429996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  bool Found = false;
4439996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
4449996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    const MachineOperand &MO = MI->getOperand(i);
4459996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
4469996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      Pred.push_back(MO);
4479996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      Found = true;
4489996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    }
4499996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  }
4509996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4519996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  return Found;
4529996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis}
4539996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4549996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// isPredicable - Return true if the specified instruction can be predicated.
4559996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// By default, this returns true for every instruction with a
4569996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// PredicateOperand.
4579996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidisbool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const {
4589996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  const TargetInstrDesc &TID = MI->getDesc();
4599996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (!TID.isPredicable())
4609996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return false;
4619996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4629996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if ((TID.TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) {
4639996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    ARMFunctionInfo *AFI =
4649996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
4659996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return AFI->isThumb2Function();
4669996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  }
4679996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  return true;
4689996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis}
4699996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4709996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
4719996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios KyrtzidisDISABLE_INLINE
4729996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidisstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
473da8249e57f3badecf925571881fe57243935c6c1Chris Lattner                                unsigned JTI);
474da8249e57f3badecf925571881fe57243935c6c1Chris Lattnerstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
475da8249e57f3badecf925571881fe57243935c6c1Chris Lattner                                unsigned JTI) {
476da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  assert(JTI < JT.size());
477da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  return JT[JTI].MBBs.size();
478ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen}
479ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen
480ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen/// GetInstSize - Return the size of the specified MachineInstr.
481da8249e57f3badecf925571881fe57243935c6c1Chris Lattner///
482da8249e57f3badecf925571881fe57243935c6c1Chris Lattnerunsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
483da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  const MachineBasicBlock &MBB = *MI->getParent();
4845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  const MachineFunction *MF = MBB.getParent();
4855cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
487a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson  // Basic size info comes from the TSFlags field.
4882085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  const TargetInstrDesc &TID = MI->getDesc();
4892085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  uint64_t TSFlags = TID.TSFlags;
4902085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
4912085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  unsigned Opc = MI->getOpcode();
4923248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner  switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
4932085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  default: {
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // If this machine instr is an inline asm, measure it.
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (MI->getOpcode() == ARM::INLINEASM)
49665aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad      return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI);
49765aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad    if (MI->isLabel())
4982085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner      return 0;
49965aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad    switch (Opc) {
5005cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    default:
5013e2193ce5feb2feb092e5ae615e85148e06e9fd2Anders Carlsson      llvm_unreachable("Unknown or unset size field for instr!");
5022085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    case TargetOpcode::IMPLICIT_DEF:
5032085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    case TargetOpcode::KILL:
5045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case TargetOpcode::DBG_LABEL:
505726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    case TargetOpcode::EH_LABEL:
5062085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    case TargetOpcode::DBG_VALUE:
5072085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner      return 0;
508726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    }
509726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    break;
510673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  }
511673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  case ARMII::Size8Bytes: return 8;          // ARM instruction x 2.
512673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  case ARMII::Size4Bytes: return 4;          // ARM / Thumb2 instruction.
5133248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner  case ARMII::Size2Bytes: return 2;          // Thumb1 instruction.
514673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  case ARMII::SizeSpecial: {
515673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    switch (Opc) {
516673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    case ARM::CONSTPOOL_ENTRY:
517673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      // If this machine instr is a constant pool entry, its size is recorded as
518673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      // operand #2.
519673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      return MI->getOperand(2).getImm();
520673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    case ARM::Int_eh_sjlj_longjmp:
5215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      return 16;
522b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar    case ARM::tInt_eh_sjlj_longjmp:
523b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar      return 10;
524673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    case ARM::Int_eh_sjlj_setjmp:
525b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar    case ARM::Int_eh_sjlj_setjmp_nofp:
526673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      return 20;
527673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    case ARM::tInt_eh_sjlj_setjmp:
52808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::t2Int_eh_sjlj_setjmp:
52908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::t2Int_eh_sjlj_setjmp_nofp:
53008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      return 12;
53108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::BR_JTr:
53208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::BR_JTm:
53308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::BR_JTadd:
53408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::tBR_JTr:
53508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::t2BR_JT:
53608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::t2TBB:
53708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    case ARM::t2TBH: {
5385cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      // These are jumptable branches, i.e. a branch followed by an inlined
5395cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      // jumptable. The size is 4 + 4 * number of entries. For TBB, each
54008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // entry is one byte; TBH two byte each.
54108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      unsigned EntrySize = (Opc == ARM::t2TBB)
54208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        ? 1 : ((Opc == ARM::t2TBH) ? 2 : 4);
54308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      unsigned NumOps = TID.getNumOperands();
54408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      MachineOperand JTOP =
54508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
54608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      unsigned JTI = JTOP.getIndex();
54708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
54808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      assert(MJTI != 0);
54908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
55008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      assert(JTI < JT.size());
55108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
55208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // 4 aligned. The assembler / linker may add 2 byte padding just before
55308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // the JT entries.  The size does not include this padding; the
55408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // constant islands pass does separate bookkeeping for it.
5555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      // FIXME: If we know the size of the function is less than (1 << 16) *2
55608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // bytes, we can use 16-bit entries instead. Then there won't be an
55708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // alignment issue.
55808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
55908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      unsigned NumEntries = getNumJTEntries(JT, JTI);
56008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      if (Opc == ARM::t2TBB && (NumEntries & 1))
56108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        // Make sure the instruction that follows TBB is 2-byte aligned.
56208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        // FIXME: Constant island pass should insert an "ALIGN" instruction
56308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        // instead.
56408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner        ++NumEntries;
56508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      return NumEntries * EntrySize + InstSize;
56608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    }
56708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    default:
56808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // Otherwise, pseudo-instruction sizes are zero.
56908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      return 0;
57008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    }
57108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  }
57208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  }
57308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  return 0; // Not reached
57408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner}
57508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
57608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner/// Return true if the instruction is a register to register move and
57708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner/// leave the source and dest operands in the passed parameters.
578935a70c1e76d78985f20d422940280161b941299Hans Wennborg///
57908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattnerbool
58008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris LattnerARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
58108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                              unsigned &SrcReg, unsigned &DstReg,
58208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                              unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
58308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  switch (MI.getOpcode()) {
58408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  default: break;
58508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  case ARM::VMOVS:
58608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  case ARM::VMOVD:
58708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  case ARM::VMOVDneon:
58808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  case ARM::VMOVQ:
58908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  case ARM::VMOVQQ : {
59008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    SrcReg = MI.getOperand(1).getReg();
59108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    DstReg = MI.getOperand(0).getReg();
59208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    SrcSubIdx = MI.getOperand(1).getSubReg();
59308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    DstSubIdx = MI.getOperand(0).getSubReg();
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ARM::MOVr:
5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ARM::MOVr_TC:
598b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  case ARM::tMOVr:
5992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tMOVgpr2tgpr:
6002de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tMOVtgpr2gpr:
6012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tMOVgpr2gpr:
6022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::t2MOVr: {
6032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    assert(MI.getDesc().getNumOperands() >= 2 &&
6042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall           MI.getOperand(0).isReg() &&
6052de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall           MI.getOperand(1).isReg() &&
6062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall           "Invalid ARM MOV instruction");
6072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    SrcReg = MI.getOperand(1).getReg();
6082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    DstReg = MI.getOperand(0).getReg();
6092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    SrcSubIdx = MI.getOperand(1).getSubReg();
6102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    DstSubIdx = MI.getOperand(0).getSubReg();
6112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    return true;
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return false;
616bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor}
617bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
618b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikieunsigned
6192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
6202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                      int &FrameIndex) const {
6212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  switch (MI->getOpcode()) {
6222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  default: break;
6232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::LDR:
6242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::t2LDRs:  // FIXME: don't use t2LDRs to access frame.
6252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (MI->getOperand(1).isFI() &&
6262de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        MI->getOperand(2).isReg() &&
627bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor        MI->getOperand(3).isImm() &&
628bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor        MI->getOperand(2).getReg() == 0 &&
629bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor        MI->getOperand(3).getImm() == 0) {
630bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor      FrameIndex = MI->getOperand(1).getIndex();
631bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor      return MI->getOperand(0).getReg();
6322de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
6332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    break;
6342de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::t2LDRi12:
6352de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tRestore:
6362de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (MI->getOperand(1).isFI() &&
6372de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        MI->getOperand(2).isImm() &&
6382de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        MI->getOperand(2).getImm() == 0) {
6392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      FrameIndex = MI->getOperand(1).getIndex();
640bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor      return MI->getOperand(0).getReg();
641bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor    }
642bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor    break;
643bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  case ARM::VLDRD:
644bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  case ARM::VLDRS:
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (MI->getOperand(1).isFI() &&
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        MI->getOperand(2).isImm() &&
6475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        MI->getOperand(2).getImm() == 0) {
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      FrameIndex = MI->getOperand(1).getIndex();
649cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      return MI->getOperand(0).getReg();
650cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    }
651f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    break;
652f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  }
653bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
654bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  return 0;
655561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor}
656bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
657898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorunsigned
6581eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
659cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne                                     int &FrameIndex) const {
660b4609806e9232593ece09ce08b630836e825865cDouglas Gregor  switch (MI->getOpcode()) {
661bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  default: break;
662bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  case ARM::STR:
663bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
664bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    if (MI->getOperand(1).isFI() &&
665bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor        MI->getOperand(2).isReg() &&
666561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        MI->getOperand(3).isImm() &&
667561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        MI->getOperand(2).getReg() == 0 &&
668bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor        MI->getOperand(3).getImm() == 0) {
669bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor      FrameIndex = MI->getOperand(1).getIndex();
670bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor      return MI->getOperand(0).getReg();
671cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    }
672bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    break;
673668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  case ARM::t2STRi12:
674cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  case ARM::tSpill:
675b4609806e9232593ece09ce08b630836e825865cDouglas Gregor    if (MI->getOperand(1).isFI() &&
676b4609806e9232593ece09ce08b630836e825865cDouglas Gregor        MI->getOperand(2).isImm() &&
677e2ce1d9440186cf3332368291cd884a6e3ae8946Nate Begeman        MI->getOperand(2).getImm() == 0) {
678668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek      FrameIndex = MI->getOperand(1).getIndex();
679f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      return MI->getOperand(0).getReg();
680f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    }
681bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    break;
682bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  case ARM::VSTRD:
683561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  case ARM::VSTRS:
684bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    if (MI->getOperand(1).isFI() &&
685898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor        MI->getOperand(2).isImm() &&
686668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek        MI->getOperand(2).getImm() == 0) {
687cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      FrameIndex = MI->getOperand(1).getIndex();
68877ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek      return MI->getOperand(0).getReg();
689bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    }
690bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    break;
691bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  }
692bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
693bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  return 0;
694561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor}
695561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
696bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregorbool
697bebbe0d9b7568ce43a464286bee49429489ef483Douglas GregorARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
698bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                               MachineBasicBlock::iterator I,
699cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne                               unsigned DestReg, unsigned SrcReg,
700bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                               const TargetRegisterClass *DestRC,
701668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek                               const TargetRegisterClass *SrcRC,
702cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne                               DebugLoc DL) const {
7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // tGPR or tcGPR is used sometimes in ARM instructions that need to avoid
7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // using certain registers.  Just treat them as GPR here.
7055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (DestRC == ARM::tGPRRegisterClass || DestRC == ARM::tcGPRRegisterClass)
7061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    DestRC = ARM::GPRRegisterClass;
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (SrcRC == ARM::tGPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass)
708bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    SrcRC = ARM::GPRRegisterClass;
709cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
710cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  if (DestRC == ARM::SPR_8RegisterClass)
711cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    DestRC = ARM::SPRRegisterClass;
712cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  if (SrcRC == ARM::SPR_8RegisterClass)
713cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    SrcRC = ARM::SPRRegisterClass;
714cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
715cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
716cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  if (DestRC == ARM::DPR_8RegisterClass)
717cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    DestRC = ARM::DPR_VFP2RegisterClass;
718cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne  if (SrcRC == ARM::DPR_8RegisterClass)
7191f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor    SrcRC = ARM::DPR_VFP2RegisterClass;
7201f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor
721d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  // NEONMoveFixPass will convert VFP moves to NEON moves when profitable.
722e8683d6d389def2fce229325435ba3c2b3f75492John McCall  if (DestRC == ARM::DPR_VFP2RegisterClass)
7231ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor    DestRC = ARM::DPRRegisterClass;
7241ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor  if (SrcRC == ARM::DPR_VFP2RegisterClass)
7251ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor    SrcRC = ARM::DPRRegisterClass;
7261ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor
7271ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor  // Allow QPR / QPR_VFP2 / QPR_8 cross-class copies.
7281ddc9c4674b7c737ec65241a531df8c64e40b0a9Douglas Gregor  if (DestRC == ARM::QPR_VFP2RegisterClass ||
729200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl      DestRC == ARM::QPR_8RegisterClass)
730200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl    DestRC = ARM::QPRRegisterClass;
731200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  if (SrcRC == ARM::QPR_VFP2RegisterClass ||
732200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl      SrcRC == ARM::QPR_8RegisterClass)
733200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl    SrcRC = ARM::QPRRegisterClass;
734200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl
735200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  // Allow QQPR / QQPR_VFP2 cross-class copies.
736200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  if (DestRC == ARM::QQPR_VFP2RegisterClass)
7376346f963145ed18b6edf50a78753b47db505e912Chris Lattner    DestRC = ARM::QQPRRegisterClass;
738d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  if (SrcRC == ARM::QQPR_VFP2RegisterClass)
739cb1c77f90d4e747b83a0d0cc125dc01567378f82Nuno Lopes    SrcRC = ARM::QQPRRegisterClass;
740cb1c77f90d4e747b83a0d0cc125dc01567378f82Nuno Lopes
741a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu  // Disallow copies of unequal sizes.
742a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu  if (DestRC != SrcRC && DestRC->getSize() != SrcRC->getSize())
743a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu    return false;
744a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu
745d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  if (DestRC == ARM::GPRRegisterClass) {
746caabf9bf331156e96dacb072385901fdfa057ec1Chris Lattner    if (SrcRC == ARM::SPRRegisterClass)
747d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVRS), DestReg)
748d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes                     .addReg(SrcReg));
749d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    else
750d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
751d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner                                          DestReg).addReg(SrcReg)));
7528189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  } else {
753d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    unsigned Opc;
754d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (DestRC == ARM::SPRRegisterClass)
756d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      Opc = (SrcRC == ARM::GPRRegisterClass ? ARM::VMOVSR : ARM::VMOVS);
757d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    else if (DestRC == ARM::DPRRegisterClass)
758d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      Opc = ARM::VMOVD;
759d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    else if (DestRC == ARM::QPRRegisterClass)
760d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      Opc = ARM::VMOVQ;
761d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    else if (DestRC == ARM::QQPRRegisterClass)
762d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      Opc = ARM::VMOVQQ;
763cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    else if (DestRC == ARM::QQQQPRRegisterClass)
764cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      Opc = ARM::VMOVQQQQ;
765d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    else
766cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      return false;
767d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
768d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg);
769cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    MIB.addReg(SrcReg);
770cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne    if (Opc != ARM::VMOVQQ && Opc != ARM::VMOVQQQQ)
771d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      AddDefaultPred(MIB);
7721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
77388c9a46f0b84f1ee83e01917825346551ee540d0Douglas Gregor
774d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  return true;
775d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner}
776d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
777d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattnerstatic const
778cb888967400a03504c88acedd5248d6778a82f46Chris LattnerMachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB,
779cb888967400a03504c88acedd5248d6778a82f46Chris Lattner                             unsigned Reg, unsigned SubIdx, unsigned State,
7804ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                             const TargetRegisterInfo *TRI) {
781c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff  if (!SubIdx)
7821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return MIB.addReg(Reg, State);
783c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff
784c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff  if (TargetRegisterInfo::isPhysicalRegister(Reg))
785c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff    return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
786cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  return MIB.addReg(Reg, State, SubIdx);
7871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
788c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff
789c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroffvoid ARMBaseInstrInfo::
790cb888967400a03504c88acedd5248d6778a82f46Chris LattnerstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
7911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    unsigned SrcReg, bool isKill, int FI,
792bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlsson                    const TargetRegisterClass *RC,
793bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlsson                    const TargetRegisterInfo *TRI) const {
794cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  DebugLoc DL;
7951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (I != MBB.end()) DL = I->getDebugLoc();
7964fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor  MachineFunction &MF = *MBB.getParent();
7974fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor  MachineFrameInfo &MFI = *MF.getFrameInfo();
7984fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor  unsigned Align = MFI.getObjectAlignment(FI);
7997814e6d6645d587891293d59ecf6576defcfac92Douglas Gregor
800cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  MachineMemOperand *MMO =
801bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlsson    MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
8026dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                            MachineMemOperand::MOStore, 0,
8036dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                            MFI.getObjectSize(FI),
8046217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek                            Align);
8056dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson
8066217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  // tGPR is used sometimes in ARM instructions that need to avoid using
8076dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson  // certain registers.  Just treat it as GPR here.
808864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall  if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass)
809864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    RC = ARM::GPRRegisterClass;
810864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall
8115291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  switch (RC->getID()) {
812864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall  case ARM::GPRRegClassID:
8136dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
8146dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                   .addReg(SrcReg, getKillRegState(isKill))
815cb888967400a03504c88acedd5248d6778a82f46Chris Lattner                   .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
8162882eca5a184c78f793188083f6ce539740a5cf2John McCall    break;
8172882eca5a184c78f793188083f6ce539740a5cf2John McCall  case ARM::SPRRegClassID:
8182882eca5a184c78f793188083f6ce539740a5cf2John McCall    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
8192882eca5a184c78f793188083f6ce539740a5cf2John McCall                   .addReg(SrcReg, getKillRegState(isKill))
8202882eca5a184c78f793188083f6ce539740a5cf2John McCall                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
8212882eca5a184c78f793188083f6ce539740a5cf2John McCall    break;
8222882eca5a184c78f793188083f6ce539740a5cf2John McCall  case ARM::DPRRegClassID:
8232882eca5a184c78f793188083f6ce539740a5cf2John McCall  case ARM::DPR_VFP2RegClassID:
8242882eca5a184c78f793188083f6ce539740a5cf2John McCall  case ARM::DPR_8RegClassID:
8252882eca5a184c78f793188083f6ce539740a5cf2John McCall    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
8262882eca5a184c78f793188083f6ce539740a5cf2John McCall                   .addReg(SrcReg, getKillRegState(isKill))
8272882eca5a184c78f793188083f6ce539740a5cf2John McCall                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
8282882eca5a184c78f793188083f6ce539740a5cf2John McCall    break;
829c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  case ARM::QPRRegClassID:
8308ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  case ARM::QPR_VFP2RegClassID:
831c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  case ARM::QPR_8RegClassID:
832c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    // FIXME: Neon instructions should support predicates
8338ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
8348ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q))
8358ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addFrameIndex(FI).addImm(16)
836c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                     .addReg(SrcReg, getKillRegState(isKill))
8378ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addMemOperand(MMO));
8388ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    } else {
8398ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQ))
8408ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addReg(SrcReg, getKillRegState(isKill))
8418ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addFrameIndex(FI)
8428ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
8438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addMemOperand(MMO));
8448ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    }
8458ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    break;
8468ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  case ARM::QQPRRegClassID:
8478ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  case ARM::QQPR_VFP2RegClassID:
8488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
8498ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // FIXME: It's possible to only store part of the QQ register if the
8508ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // spilled def has a sub-register index.
851c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST2q32))
8528ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        .addFrameIndex(FI).addImm(16);
853c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
8548ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
8558ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
856f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
857f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      AddDefaultPred(MIB.addMemOperand(MMO));
858bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    } else {
859561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      MachineInstrBuilder MIB =
860bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD))
861c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                       .addFrameIndex(FI)
862c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                       .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
8638ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        .addMemOperand(MMO);
8648ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
8658ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
8668ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
867c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt            AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
8688ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    }
869bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    break;
870bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  case ARM::QQQQPRRegClassID: {
871bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    MachineInstrBuilder MIB =
872bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD))
873bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                     .addFrameIndex(FI)
8748ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
8758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      .addMemOperand(MMO);
8768ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
8778ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
8788ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
8798ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
8808ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
8818ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
882c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
8838ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor          AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
8848ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    break;
8858ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  }
8861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  default:
88740d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor    llvm_unreachable("Unknown regclass!");
888f595cc41c4d95fe323f8a2b209523de9956f874dEli Friedman  }
889161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
8902577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
891d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallvoid ARMBaseInstrInfo::
892f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCallloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
893f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                     unsigned DestReg, int FI,
894f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                     const TargetRegisterClass *RC,
89583f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor                     const TargetRegisterInfo *TRI) const {
8966bb8017bb9e828d118e15e59d71c66bba323c364John McCall  DebugLoc DL;
89740d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor  if (I != MBB.end()) DL = I->getDebugLoc();
898161755a09898c95d21bfff33707da9ca41cd53c5John McCall  MachineFunction &MF = *MBB.getParent();
899161755a09898c95d21bfff33707da9ca41cd53c5John McCall  MachineFrameInfo &MFI = *MF.getFrameInfo();
9006bb8017bb9e828d118e15e59d71c66bba323c364John McCall  unsigned Align = MFI.getObjectAlignment(FI);
9016bb8017bb9e828d118e15e59d71c66bba323c364John McCall  MachineMemOperand *MMO =
9021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
903d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                            MachineMemOperand::MOLoad, 0,
904b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis                            MFI.getObjectSize(FI),
9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                            Align);
9063248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner
907f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // tGPR is used sometimes in ARM instructions that need to avoid using
908f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // certain registers.  Just treat it as GPR here.
9096bb8017bb9e828d118e15e59d71c66bba323c364John McCall  if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass)
9106bb8017bb9e828d118e15e59d71c66bba323c364John McCall    RC = ARM::GPRRegisterClass;
91140d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor
91240d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor  switch (RC->getID()) {
9136bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::GPRRegClassID:
9146bb8017bb9e828d118e15e59d71c66bba323c364John McCall    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
915561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                   .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
916561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    break;
917561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  case ARM::SPRRegClassID:
918561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
919561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
920561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    break;
9216bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::DPRRegClassID:
9226bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::DPR_VFP2RegClassID:
9236bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::DPR_8RegClassID:
92440d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
9256bb8017bb9e828d118e15e59d71c66bba323c364John McCall                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
9266bb8017bb9e828d118e15e59d71c66bba323c364John McCall    break;
9276bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::QPRRegClassID:
9286bb8017bb9e828d118e15e59d71c66bba323c364John McCall  case ARM::QPR_VFP2RegClassID:
929561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  case ARM::QPR_8RegClassID:
930561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
931561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q), DestReg)
9326bb8017bb9e828d118e15e59d71c66bba323c364John McCall                     .addFrameIndex(FI).addImm(16)
933561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                     .addMemOperand(MMO));
934561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    } else {
935561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQ), DestReg)
936561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                     .addFrameIndex(FI)
937561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                     .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
9386bb8017bb9e828d118e15e59d71c66bba323c364John McCall                     .addMemOperand(MMO));
9396bb8017bb9e828d118e15e59d71c66bba323c364John McCall    }
9406bb8017bb9e828d118e15e59d71c66bba323c364John McCall    break;
94183f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor  case ARM::QQPRRegClassID:
94283f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor  case ARM::QQPR_VFP2RegClassID:
94375e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
94475e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD2q32));
94575e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI);
94675e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI);
94775e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI);
94875e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI);
94975e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      AddDefaultPred(MIB.addFrameIndex(FI).addImm(16).addMemOperand(MMO));
95075e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    } else {
95175e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MachineInstrBuilder MIB =
95275e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor        AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD))
95375e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor                       .addFrameIndex(FI)
95475e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor                       .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
95575e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor        .addMemOperand(MMO);
95675e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI);
95775e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI);
95875e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI);
95975e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor            AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI);
96075e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    }
96175e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    break;
96275e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor  case ARM::QQQQPRRegClassID: {
96375e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    MachineInstrBuilder MIB =
96475e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor      AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD))
9651d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                     .addFrameIndex(FI)
9661d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                     .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
9671d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      .addMemOperand(MMO);
9681d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI);
9691d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI);
9701d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI);
9711d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI);
9721d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::Define, TRI);
9731d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::Define, TRI);
9741d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::Define, TRI);
9751d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    AddDReg(MIB, DestReg, ARM::dsub_7, RegState::Define, TRI);
9761d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    break;
9771d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  }
9781d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  default:
9791d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    llvm_unreachable("Unknown regclass!");
9801d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  }
9811d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall}
9821d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall
9831d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCallMachineInstr*
9841d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCallARMBaseInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
9851d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                                           int FrameIx, uint64_t Offset,
9861d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                                           const MDNode *MDPtr,
9871d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                                           DebugLoc DL) const {
9881d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::DBG_VALUE))
9891d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
9901d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  return &*MIB;
9911d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall}
9921d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall
9931d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCallMachineInstr *ARMBaseInstrInfo::
9941d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCallfoldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
9951d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                      const SmallVectorImpl<unsigned> &Ops, int FI) const {
9961d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  if (Ops.size() != 1) return NULL;
9971d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall
9981d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  unsigned OpNum = Ops[0];
9991d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  unsigned Opc = MI->getOpcode();
10001d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  MachineInstr *NewMI = NULL;
10011d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) {
10021d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    // If it is updating CPSR, then it cannot be folded.
10031d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    if (MI->getOperand(4).getReg() == ARM::CPSR && !MI->getOperand(4).isDead())
10041d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      return NULL;
10051d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    unsigned Pred = MI->getOperand(2).getImm();
10061d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    unsigned PredReg = MI->getOperand(3).getReg();
10071d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    if (OpNum == 0) { // move -> store
10081d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned SrcReg = MI->getOperand(1).getReg();
10091d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned SrcSubReg = MI->getOperand(1).getSubReg();
10101d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      bool isKill = MI->getOperand(1).isKill();
10111d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      bool isUndef = MI->getOperand(1).isUndef();
10121d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      if (Opc == ARM::MOVr)
10131d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
10141d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addReg(SrcReg,
10151d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getKillRegState(isKill) | getUndefRegState(isUndef),
10161d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  SrcSubReg)
10171d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
10181d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      else // ARM::t2MOVr
10191d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12))
10201d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addReg(SrcReg,
10211d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getKillRegState(isKill) | getUndefRegState(isUndef),
10221d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  SrcSubReg)
10231d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
10241d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    } else {          // move -> load
10251d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned DstReg = MI->getOperand(0).getReg();
10261d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned DstSubReg = MI->getOperand(0).getSubReg();
10271d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      bool isDead = MI->getOperand(0).isDead();
102833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      bool isUndef = MI->getOperand(0).isUndef();
102933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      if (Opc == ARM::MOVr)
103033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
103133e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall          .addReg(DstReg,
10321d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  RegState::Define |
10331d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getDeadRegState(isDead) |
10341d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getUndefRegState(isUndef), DstSubReg)
10351d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
10361d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      else // ARM::t2MOVr
10371d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12))
10381d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addReg(DstReg,
10391d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  RegState::Define |
10401d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getDeadRegState(isDead) |
10411d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                  getUndefRegState(isUndef), DstSubReg)
10421d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall          .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
10431d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    }
10441d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  } else if (Opc == ARM::tMOVgpr2gpr ||
10451d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall             Opc == ARM::tMOVtgpr2gpr ||
10461d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall             Opc == ARM::tMOVgpr2tgpr) {
10471d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    if (OpNum == 0) { // move -> store
10481d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned SrcReg = MI->getOperand(1).getReg();
10491d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      unsigned SrcSubReg = MI->getOperand(1).getSubReg();
10501d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      bool isKill = MI->getOperand(1).isKill();
10511d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      bool isUndef = MI->getOperand(1).isUndef();
10521d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12))
1053f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson        .addReg(SrcReg,
1054f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                getKillRegState(isKill) | getUndefRegState(isUndef),
1055daa8e4e888758d55a7a759dd4a91b83921cef222John McCall                SrcSubReg)
1056daa8e4e888758d55a7a759dd4a91b83921cef222John McCall        .addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0);
10572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    } else {          // move -> load
1058f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson      unsigned DstReg = MI->getOperand(0).getReg();
10592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      unsigned DstSubReg = MI->getOperand(0).getSubReg();
1060e39a3894513349908cdb3beba2614e53cb288e6cDouglas Gregor      bool isDead = MI->getOperand(0).isDead();
10610ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall      bool isUndef = MI->getOperand(0).isUndef();
10620ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12))
1063f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall        .addReg(DstReg,
1064f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall                RegState::Define |
10652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                getDeadRegState(isDead) |
1066f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                getUndefRegState(isUndef),
10672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                DstSubReg)
106811de6de25a0110cd7be97eef761ef3b189781da6Anders Carlsson        .addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0);
10692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
1070f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  } else if (Opc == ARM::VMOVS) {
10712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    unsigned Pred = MI->getOperand(2).getImm();
107223cba801e11b03929c44f8cf54578305963a3476John McCall    unsigned PredReg = MI->getOperand(3).getReg();
10732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (OpNum == 0) { // move -> store
1074f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson      unsigned SrcReg = MI->getOperand(1).getReg();
10752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      unsigned SrcSubReg = MI->getOperand(1).getSubReg();
1076f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson      bool isKill = MI->getOperand(1).isKill();
10772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      bool isUndef = MI->getOperand(1).isUndef();
1078f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRS))
10792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef),
1080f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                SrcSubReg)
10812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        .addFrameIndex(FI)
1082f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson        .addImm(0).addImm(Pred).addReg(PredReg);
1083404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall    } else {          // move -> load
1084404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall      unsigned DstReg = MI->getOperand(0).getReg();
10852de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      unsigned DstSubReg = MI->getOperand(0).getSubReg();
1086f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson      bool isDead = MI->getOperand(0).isDead();
10872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      bool isUndef = MI->getOperand(0).isUndef();
10881a31a18db9d657751f38c724adc0d62e86852bd7Anders Carlsson      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRS))
10892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        .addReg(DstReg,
1090f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                RegState::Define |
10912de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                getDeadRegState(isDead) |
1092f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                getUndefRegState(isUndef),
10932de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                DstSubReg)
10947f9e646b7ed47bc8e9a60031ad0c2b55031e2077Anders Carlsson        .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
10952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
10967f9e646b7ed47bc8e9a60031ad0c2b55031e2077Anders Carlsson  } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVDneon) {
1097daa8e4e888758d55a7a759dd4a91b83921cef222John McCall    unsigned Pred = MI->getOperand(2).getImm();
1098daa8e4e888758d55a7a759dd4a91b83921cef222John McCall    unsigned PredReg = MI->getOperand(3).getReg();
10992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (OpNum == 0) { // move -> store
1100ebeaf2031c968143c531bfe232d7507f20c57347Anders Carlsson      unsigned SrcReg = MI->getOperand(1).getReg();
11012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      unsigned SrcSubReg = MI->getOperand(1).getSubReg();
110216a8904f3f5ed19158657e1da95e5902fbee66f7Anders Carlsson      bool isKill = MI->getOperand(1).isKill();
11032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      bool isUndef = MI->getOperand(1).isUndef();
110482debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlsson      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRD))
1105daa8e4e888758d55a7a759dd4a91b83921cef222John McCall        .addReg(SrcReg,
1106daa8e4e888758d55a7a759dd4a91b83921cef222John McCall                getKillRegState(isKill) | getUndefRegState(isUndef),
11072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                SrcSubReg)
110882debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlsson        .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
11092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    } else {          // move -> load
111082debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlsson      unsigned DstReg = MI->getOperand(0).getReg();
11112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      unsigned DstSubReg = MI->getOperand(0).getSubReg();
1112c6b29163557d02da5d2a4a06f986f0480291f51fBenjamin Kramer      bool isDead = MI->getOperand(0).isDead();
1113daa8e4e888758d55a7a759dd4a91b83921cef222John McCall      bool isUndef = MI->getOperand(0).isUndef();
1114daa8e4e888758d55a7a759dd4a91b83921cef222John McCall      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRD))
11152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall        .addReg(DstReg,
1116bc0e0781da778bd5eb41a810419912893ae20448Anders Carlsson                RegState::Define |
11171d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                getDeadRegState(isDead) |
11181d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                getUndefRegState(isUndef),
11191d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                DstSubReg)
11201d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
11212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
11223b27f1a80e4e433b503efd344c909eeafaa9033cFariborz Jahanian  }  else if (Opc == ARM::VMOVQ) {
11232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    MachineFrameInfo &MFI = *MF.getFrameInfo();
1124569c3166874324c24011f8ade6978421f0d39b3cDouglas Gregor    unsigned Pred = MI->getOperand(2).getImm();
11252bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall    unsigned PredReg = MI->getOperand(3).getReg();
11262bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall    if (OpNum == 0) { // move -> store
1127f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall      unsigned SrcReg = MI->getOperand(1).getReg();
1128f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall      unsigned SrcSubReg = MI->getOperand(1).getSubReg();
1129f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall      bool isKill = MI->getOperand(1).isKill();
1130f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall      bool isUndef = MI->getOperand(1).isUndef();
11312bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall      if (MFI.getObjectAlignment(FI) >= 16 &&
11322bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall          getRegisterInfo().canRealignStack(MF)) {
1133f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VST1q))
1134f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall          .addFrameIndex(FI).addImm(16)
11352bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall          .addReg(SrcReg,
11362bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall                  getKillRegState(isKill) | getUndefRegState(isUndef),
1137f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall                  SrcSubReg)
1138f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall          .addImm(Pred).addReg(PredReg);
1139f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall      } else {
1140f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTMQ))
11412bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall          .addReg(SrcReg,
11422bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall                  getKillRegState(isKill) | getUndefRegState(isUndef),
1143f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall                  SrcSubReg)
1144f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall          .addFrameIndex(FI).addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
114533e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall          .addImm(Pred).addReg(PredReg);
114633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      }
114733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    } else {          // move -> load
114833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      unsigned DstReg = MI->getOperand(0).getReg();
114933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      unsigned DstSubReg = MI->getOperand(0).getSubReg();
115033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      bool isDead = MI->getOperand(0).isDead();
115133e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      bool isUndef = MI->getOperand(0).isUndef();
115233e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      if (MFI.getObjectAlignment(FI) >= 16 &&
1153f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson          getRegisterInfo().canRealignStack(MF)) {
11541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLD1q))
11552bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall          .addReg(DstReg,
1156f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                  RegState::Define |
1157f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                  getDeadRegState(isDead) |
1158f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                  getUndefRegState(isUndef),
11596eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                  DstSubReg)
11606eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor          .addFrameIndex(FI).addImm(16).addImm(Pred).addReg(PredReg);
11616eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor      } else {
11626eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor        NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDMQ))
11636eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor          .addReg(DstReg,
116403e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor                  RegState::Define |
116503e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor                  getDeadRegState(isDead) |
116603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor                  getUndefRegState(isUndef),
116703e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor                  DstSubReg)
116803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor          .addFrameIndex(FI).addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
116903e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor          .addImm(Pred).addReg(PredReg);
11706eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor      }
11716eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    }
11726eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  }
1173c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
11746eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  return NewMI;
11756eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor}
11762de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
11776eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas GregorMachineInstr*
11782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
11796eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                                        MachineInstr* MI,
1180c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                        const SmallVectorImpl<unsigned> &Ops,
11816eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                                        MachineInstr* LoadMI) const {
11826eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  // FIXME
1183c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  return 0;
1184c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt}
11856eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
11866eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregorbool
11876eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas GregorARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
1188f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                   const SmallVectorImpl<unsigned> &Ops) const {
1189f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  if (Ops.size() != 1) return false;
1190f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
1191f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  unsigned Opc = MI->getOpcode();
1192f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) {
1193f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    // If it is updating CPSR, then it cannot be folded.
1194f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    return MI->getOperand(4).getReg() != ARM::CPSR ||
1195f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall      MI->getOperand(4).isDead();
1196f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  } else if (Opc == ARM::tMOVgpr2gpr ||
1197f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall             Opc == ARM::tMOVtgpr2gpr ||
1198f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall             Opc == ARM::tMOVgpr2tgpr) {
1199f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    return true;
1200f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  } else if (Opc == ARM::VMOVS || Opc == ARM::VMOVD ||
1201f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall             Opc == ARM::VMOVDneon || Opc == ARM::VMOVQ) {
1202f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    return true;
1203f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  }
1204f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
1205f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // FIXME: VMOVQQ and VMOVQQQQ?
1206f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
1207f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  return false;
1208f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall}
1209f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
12105baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall/// Create a copy of a const pool value. Update CPI to the new index and return
1211f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall/// the label UID.
1212f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallstatic unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
1213f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  MachineConstantPool *MCP = MF.getConstantPool();
1214f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
12155baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall
1216f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
1217f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  assert(MCPE.isMachineConstantPoolEntry() &&
1218f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall         "Expecting a machine constantpool entry!");
1219f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  ARMConstantPoolValue *ACPV =
1220f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
1221f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
1222f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  unsigned PCLabelId = AFI->createConstPoolEntryUId();
1223f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  ARMConstantPoolValue *NewCPV = 0;
1224f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  if (ACPV->isGlobalValue())
1225f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
1226f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                      ARMCP::CPValue, 4);
1227f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  else if (ACPV->isExtSymbol())
1228f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
1229f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                      ACPV->getSymbol(), PCLabelId, 4);
1230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  else if (ACPV->isBlockAddress())
1231f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
1232f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                      ARMCP::CPBlockAddress, 4);
1233f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  else
1234f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    llvm_unreachable("Unexpected ARM constantpool value type!!");
1235f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
1236f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  return PCLabelId;
1237f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall}
1238f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
1239f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallvoid ARMBaseInstrInfo::
1240f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallreMaterialize(MachineBasicBlock &MBB,
1241f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall              MachineBasicBlock::iterator I,
1242f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall              unsigned DestReg, unsigned SubIdx,
1243f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall              const MachineInstr *Orig,
1244f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall              const TargetRegisterInfo &TRI) const {
1245f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  unsigned Opcode = Orig->getOpcode();
1246f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  switch (Opcode) {
1247f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  default: {
12485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
12495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MI->substituteRegister(Orig->getOperand(0).getReg(), DestReg, SubIdx, TRI);
12505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MBB.insert(I, MI);
12515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
12522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tLDRpci_pic:
12542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::t2LDRpci_pic: {
12552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    MachineFunction &MF = *MBB.getParent();
12562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    unsigned CPI = Orig->getOperand(1).getIndex();
12572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    unsigned PCLabelId = duplicateCPV(MF, CPI);
12582de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode),
12592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                      DestReg)
12602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      .addConstantPoolIndex(CPI).addImm(PCLabelId);
12612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    (*MIB).setMemRefs(Orig->memoperands_begin(), Orig->memoperands_end());
12622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    break;
12632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
12662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
12672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallMachineInstr *
12682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
12692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  MachineInstr *MI = TargetInstrInfoImpl::duplicate(Orig, MF);
12702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  switch(Orig->getOpcode()) {
12712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::tLDRpci_pic:
12722de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case ARM::t2LDRpci_pic: {
12732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    unsigned CPI = Orig->getOperand(1).getIndex();
12742de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    unsigned PCLabelId = duplicateCPV(MF, CPI);
12752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    Orig->getOperand(1).setIndex(CPI);
12762de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    Orig->getOperand(2).setImm(PCLabelId);
12772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    break;
12782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12802de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return MI;
12812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
12822de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
12832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallbool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
12845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                        const MachineInstr *MI1) const {
1285baf534875ed0a55c6342636ff3f4602b8ac22b69Douglas Gregor  int Opcode = MI0->getOpcode();
1286baf534875ed0a55c6342636ff3f4602b8ac22b69Douglas Gregor  if (Opcode == ARM::t2LDRpci ||
12875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Opcode == ARM::t2LDRpci_pic ||
12885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Opcode == ARM::tLDRpci ||
12892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      Opcode == ARM::tLDRpci_pic) {
1290063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    if (MI1->getOpcode() != Opcode)
1291063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor      return false;
1292b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    if (MI0->getNumOperands() != MI1->getNumOperands())
12932de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      return false;
12942de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
12952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineOperand &MO0 = MI0->getOperand(1);
12962de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineOperand &MO1 = MI1->getOperand(1);
12972de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (MO0.getOffset() != MO1.getOffset())
12982de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      return false;
12992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
13002de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineFunction *MF = MI0->getParent()->getParent();
13012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineConstantPool *MCP = MF->getConstantPool();
13022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    int CPI0 = MO0.getIndex();
13032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    int CPI1 = MO1.getIndex();
13042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineConstantPoolEntry &MCPE0 = MCP->getConstants()[CPI0];
13052de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const MachineConstantPoolEntry &MCPE1 = MCP->getConstants()[CPI1];
13062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    ARMConstantPoolValue *ACPV0 =
13072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      static_cast<ARMConstantPoolValue*>(MCPE0.Val.MachineCPVal);
13082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    ARMConstantPoolValue *ACPV1 =
13092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      static_cast<ARMConstantPoolValue*>(MCPE1.Val.MachineCPVal);
13102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    return ACPV0->hasSameValue(ACPV1);
13112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
13122de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
13132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
13142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
13152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
13162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
13172de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// determine if two loads are loading from the same base address. It should
13182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// only return true if the base pointers are the same and the only differences
13192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// between the two addresses is the offset. It also returns the offsets by
13202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// reference.
13212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallbool ARMBaseInstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
13222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                               int64_t &Offset1,
13232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                               int64_t &Offset2) const {
1324063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  // Don't worry about Thumb: just ARM and Thumb2.
1325063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  if (Subtarget.isThumb1Only()) return false;
1326063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1327063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
1328063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    return false;
1329063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1330063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  switch (Load1->getMachineOpcode()) {
1331063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  default:
1332063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    return false;
1333063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDR:
1334063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDRB:
1335063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDRD:
1336063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDRH:
1337063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDRSB:
1338063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::LDRSH:
1339063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::VLDRD:
1340063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::VLDRS:
1341063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::t2LDRi8:
1342063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::t2LDRDi8:
1343063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::t2LDRSHi8:
1344063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::t2LDRi12:
1345063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  case ARM::t2LDRSHi12:
1346063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    break;
1347063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  }
1348063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1349063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  switch (Load2->getMachineOpcode()) {
1350063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  default:
1351709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek    return false;
1352418f6c7d142e5ff4607f70cd8431d008442bafe9Chris Lattner  case ARM::LDR:
13534c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  case ARM::LDRB:
1354bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  case ARM::LDRD:
1355561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  case ARM::LDRH:
1356709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  case ARM::LDRSB:
13571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case ARM::LDRSH:
13584423ac0282acb8ba801eb05b38712438dc0c1e3eArgyrios Kyrtzidis  case ARM::VLDRD:
1359c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  case ARM::VLDRS:
1360ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek  case ARM::t2LDRi8:
1361ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek  case ARM::t2LDRDi8:
13628e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  case ARM::t2LDRSHi8:
1363ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek  case ARM::t2LDRi12:
13648e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  case ARM::t2LDRSHi12:
1365561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    break;
1366561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
1367bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
1368bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  // Check if base addresses and chain operands match.
136973460a32bc5299a5927d23d2e464d72af796eabfDouglas Gregor  if (Load1->getOperand(0) != Load2->getOperand(0) ||
1370c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      Load1->getOperand(4) != Load2->getOperand(4))
1371709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek    return false;
137266b5a8a39088598c01a9fa6f032dc908612dc8ecAnders Carlsson
13735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Index should be Reg0.
1374709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  if (Load1->getOperand(3) != Load2->getOperand(3))
1375ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    return false;
1376709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek
1377fa2192042f223b5122a9e17719930f77634fd31fDouglas Gregor  // Determine the offsets.
1378fa2192042f223b5122a9e17719930f77634fd31fDouglas Gregor  if (isa<ConstantSDNode>(Load1->getOperand(1)) &&
1379709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek      isa<ConstantSDNode>(Load2->getOperand(1))) {
1380709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek    Offset1 = cast<ConstantSDNode>(Load1->getOperand(1))->getSExtValue();
13814c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    Offset2 = cast<ConstantSDNode>(Load2->getOperand(1))->getSExtValue();
13824c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    return true;
1383709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  }
1384ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek
1385709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  return false;
1386ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek}
1387ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek
13884c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
13891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
13904c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// be scheduled togther. On some targets if two loads are loading from
13914c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// addresses in the same cache line, it's better if they are scheduled
13924c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// together. This function takes two integers that represent the load offsets
13934c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// from the common base address. It returns true if it decides it's desirable
13944c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor/// to schedule the two loads together. "NumLoads" is the number of loads that
13953e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis/// have already been scheduled after Load1.
13963e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidisbool ARMBaseInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
13973e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis                                               int64_t Offset1, int64_t Offset2,
13983e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis                                               unsigned NumLoads) const {
13993e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis  // Don't worry about Thumb: just ARM and Thumb2.
14003e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis  if (Subtarget.isThumb1Only()) return false;
14013e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis
14023e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis  assert(Offset2 > Offset1);
14033e8dc2ac8926dfbebd8f2f6b74ceba4befccd4d2Argyrios Kyrtzidis
1404c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  if ((Offset2 - Offset1) / 8 > 64)
1405c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    return false;
1406c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1407c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  if (Load1->getMachineOpcode() != Load2->getMachineOpcode())
1408c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    return false;  // FIXME: overly conservative?
1409c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1410c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // Four loads in a row should be sufficient.
1411c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  if (NumLoads >= 3)
1412c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    return false;
1413c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1414c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  return true;
1415c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek}
1416c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1417c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenekbool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
1418c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek                                            const MachineBasicBlock *MBB,
1419c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek                                            const MachineFunction &MF) const {
1420c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // Debug info is never a scheduling boundary. It's necessary to be explicit
1421c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // due to the special treatment of IT instructions below, otherwise a
1422c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // dbg_value followed by an IT will result in the IT instruction being
1423c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // considered a scheduling hazard, which is wrong. It should be the actual
1424c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // instruction preceding the dbg_value instruction(s), just like it is
1425c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // when debug info is not present.
1426c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  if (MI->isDebugValue())
1427c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    return false;
1428c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1429c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  // Terminators and labels can't be scheduled around.
1430c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  if (MI->getDesc().isTerminator() || MI->isLabel())
1431c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    return true;
1432c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1433bfdcae678d44906293e21c0cddc6537f3ee8b5a4Steve Naroff  // Treat the start of the IT block as a scheduling boundary, but schedule
14344eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  // t2IT along with all instructions following it.
14354eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  // FIXME: This is a big hammer. But the alternative is to add all potential
14366217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  // true and anti dependencies to IT block instructions as implicit operands
1437183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  // to the t2IT instruction. The added compile time and complexity does not
14384eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  // seem worth it.
14394eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  MachineBasicBlock::const_iterator I = MI;
14401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Make sure to skip any dbg_value instructions
14411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  while (++I != MBB->end() && I->isDebugValue())
144256ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff    ;
14431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (I != MBB->end() && I->getOpcode() == ARM::t2IT)
14447297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor    return true;
14457297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Don't attempt to schedule around any instruction that defines
14471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // a stack-oriented pointer, as it's unlikely to be profitable. This
14487297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor  // saves compile time, because it doesn't require every single
144956ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  // stack slot reference to depend on the instruction that does the
145056ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  // modification.
14515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (MI->definesRegister(ARM::SP))
14525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
14535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
1455026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1456026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1457026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerbool ARMBaseInstrInfo::
1458026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris LattnerisProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
1459026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (!NumInstrs)
1460df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    return false;
1461ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson  if (Subtarget.getCPUString() == "generic")
1462ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson    // Generic (and overly aggressive) if-conversion limits for testing.
1463ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson    return NumInstrs <= 10;
1464ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson  else if (Subtarget.hasV7Ops())
14651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return NumInstrs <= 3;
14665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return NumInstrs <= 2;
14675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14680faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall
14690faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCallbool ARMBaseInstrInfo::
1470026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris LattnerisProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
1471026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                    MachineBasicBlock &FMBB, unsigned NumF) const {
1472026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  return NumT && NumF && NumT <= 2 && NumF <= 2;
14735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1474026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1475df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump/// getInstrPredicate - If instruction is predicated, returns its predicate
1476f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne/// condition, otherwise returns AL. It also returns the condition code
1477f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne/// register by reference.
1478f111d935722ed488144600cea5ed03a6b5069e8fPeter CollingbourneARMCC::CondCodes
14795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerllvm::getInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
14805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  int PIdx = MI->findFirstPredOperandIdx();
14811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (PIdx == -1) {
14825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PredReg = 0;
1483026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return ARMCC::AL;
14842de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
14852de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
14862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  PredReg = MI->getOperand(PIdx+1).getReg();
14872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
1488026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
14892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
14905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1491df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stumpint llvm::getMatchingCondBranchOpcode(int Opc) {
1492026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Opc == ARM::B)
1493026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return ARM::Bcc;
14942de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  else if (Opc == ARM::tB)
14952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    return ARM::tBcc;
14965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else if (Opc == ARM::t2B)
1497df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump      return ARM::t2Bcc;
1498df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump
1499026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm_unreachable("Unknown unconditional branch opcode!");
1500026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  return 0;
15012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
1502df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump
15035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1504026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnervoid llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
1505026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                               MachineBasicBlock::iterator &MBBI, DebugLoc dl,
1506026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                               unsigned DestReg, unsigned BaseReg, int NumBytes,
15075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               ARMCC::CondCodes Pred, unsigned PredReg,
1508e7716e6133e23e4a89248a65a388bc840d8c130cChris Lattner                               const ARMBaseInstrInfo &TII) {
1509026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  bool isSub = NumBytes < 0;
1510c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  if (isSub) NumBytes = -NumBytes;
1511c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek
1512c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  while (NumBytes) {
151325973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
151425973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
15152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    assert(ThisVal && "Didn't extract field correctly");
1516c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek
1517c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek    // We will handle these bits from offset, clear them.
1518c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek    NumBytes &= ~ThisVal;
1519c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek
1520c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek    assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
1521c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek
152225973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    // Build the new ADD / SUB.
152325973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
15242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
15252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      .addReg(BaseReg, RegState::Kill).addImm(ThisVal)
152625973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis      .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
152725973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    BaseReg = DestReg;
152825973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis  }
152925973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis}
1530bf0ee354163f87623a4b60412544243911332343John McCall
1531026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerbool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
1532026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                                unsigned FrameReg, int &Offset,
1533026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                                const ARMBaseInstrInfo &TII) {
1534026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  unsigned Opcode = MI.getOpcode();
1535026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  const TargetInstrDesc &Desc = MI.getDesc();
1536026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1537e7716e6133e23e4a89248a65a388bc840d8c130cChris Lattner  bool isSub = false;
1538eb14fe839ec24c2ca14e5f094be147a34e3d3339Chris Lattner
1539c6dfe194f623b02c123759f235b504d4850fc178Douglas Gregor  // Memory operands in inline assembly always use AddrMode2.
1540026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Opcode == ARM::INLINEASM)
15415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddrMode = ARMII::AddrMode2;
1542ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian
1543fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek  if (Opcode == ARM::ADDri) {
1544fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek    Offset += MI.getOperand(FrameRegIdx+1).getImm();
1545fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek    if (Offset == 0) {
1546ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian      // Turn it into a move.
1547fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek      MI.setDesc(TII.get(ARM::MOVr));
1548fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1549fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek      MI.RemoveOperand(FrameRegIdx+1);
1550026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      Offset = 0;
1551fb7cb35fa0a8131853b1b049ca7be77980e144f5Ted Kremenek      return true;
1552ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian    } else if (Offset < 0) {
1553ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian      Offset = -Offset;
15545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      isSub = true;
1555026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      MI.setDesc(TII.get(ARM::SUBri));
1556026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    }
1557df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump
1558026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    // Common case: small offset, fits into instruction.
1559026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    if (ARM_AM::getSOImmVal(Offset) != -1) {
1560026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      // Replace the FrameIndex with sp / fp
1561026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1562026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
15631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Offset = 0;
15645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return true;
15655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1566026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1567df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    // Otherwise, pull as much of the immedidate into this ADDri/SUBri
1568026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    // as possible.
1569026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
1570026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
1571026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1572026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    // We will handle these bits from offset, clear them.
1573211f6adf1301a1461015fb6cb08a05f0a35b65f3Eli Friedman    Offset &= ~ThisImmVal;
15749b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth
15759b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    // Get the properly encoded SOImmVal field.
15769b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
15779b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth           "Bit extraction didn't work?");
15789b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
15799b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth } else {
15809b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    unsigned ImmIdx = 0;
15819b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    int InstrOffs = 0;
15829b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth    unsigned NumBits = 0;
15836e5218367c513fe02d1c7210023d40739ecb1572Matt Beaumont-Gay    unsigned Scale = 1;
15846e5218367c513fe02d1c7210023d40739ecb1572Matt Beaumont-Gay    switch (AddrMode) {
15856e5218367c513fe02d1c7210023d40739ecb1572Matt Beaumont-Gay    case ARMII::AddrMode2: {
15869b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth      ImmIdx = FrameRegIdx+2;
15876e5218367c513fe02d1c7210023d40739ecb1572Matt Beaumont-Gay      InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
15889b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth      if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
15899b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth        InstrOffs *= -1;
15909b10683a3f222d8dc6e139073ca96b97b439747bChandler Carruth      NumBits = 12;
15915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      break;
1592852871abbff45f1c1d3787755a27fce08365b166Eli Friedman    }
1593026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    case ARMII::AddrMode3: {
1594026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      ImmIdx = FrameRegIdx+2;
1595d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes      InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
1596026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1597026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner        InstrOffs *= -1;
1598bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      NumBits = 8;
1599bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      break;
1600bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    }
1601bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    case ARMII::AddrMode4:
1602bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    case ARMII::AddrMode6:
1603bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      // Can't fold any offset even if it's zero.
1604bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      return false;
1605bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    case ARMII::AddrMode5: {
1606bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      ImmIdx = FrameRegIdx+1;
1607bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1608bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1609bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner        InstrOffs *= -1;
1610bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      NumBits = 8;
1611026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      Scale = 4;
1612026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      break;
1613026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    }
161458beed91d468863b8c85bce43425422703838d27Anders Carlsson    default:
161558beed91d468863b8c85bce43425422703838d27Anders Carlsson      llvm_unreachable("Unsupported addressing mode!");
161658beed91d468863b8c85bce43425422703838d27Anders Carlsson      break;
161758beed91d468863b8c85bce43425422703838d27Anders Carlsson    }
161858beed91d468863b8c85bce43425422703838d27Anders Carlsson
1619f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    Offset += InstrOffs * Scale;
1620f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1621f85e193739c953358c865005855253af4f68a497John McCall    if (Offset < 0) {
1622f85e193739c953358c865005855253af4f68a497John McCall      Offset = -Offset;
1623f85e193739c953358c865005855253af4f68a497John McCall      isSub = true;
1624f85e193739c953358c865005855253af4f68a497John McCall    }
1625f85e193739c953358c865005855253af4f68a497John McCall
1626f85e193739c953358c865005855253af4f68a497John McCall    // Attempt to fold address comp. if opcode has offset bits
1627f85e193739c953358c865005855253af4f68a497John McCall    if (NumBits > 0) {
1628f85e193739c953358c865005855253af4f68a497John McCall      // Common case: small offset, fits into instruction.
1629f85e193739c953358c865005855253af4f68a497John McCall      MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1630f85e193739c953358c865005855253af4f68a497John McCall      int ImmedOffset = Offset / Scale;
1631f85e193739c953358c865005855253af4f68a497John McCall      unsigned Mask = (1 << NumBits) - 1;
1632f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      if ((unsigned)Offset <= Mask * Scale) {
1633f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian        // Replace the FrameIndex with sp
1634f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1635f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian        if (isSub)
1636f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian          ImmedOffset |= 1 << NumBits;
1637026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner        ImmOp.ChangeToImmediate(ImmedOffset);
1638f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian        Offset = 0;
16391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return true;
164012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall      }
16415e94a0d82b1f49be41c35a73106b219e3f588c8cChris Lattner
16425e94a0d82b1f49be41c35a73106b219e3f588c8cChris Lattner      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1643a50089ec68a583d13718107c1b0c898f0903709eChris Lattner      ImmedOffset = ImmedOffset & Mask;
164412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall      if (isSub)
1645611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner        ImmedOffset |= 1 << NumBits;
1646611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      ImmOp.ChangeToImmediate(ImmedOffset);
1647611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Offset &= ~(Mask*Scale);
1648611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner    }
1649611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner  }
1650611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner
1651611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner  Offset = (isSub) ? -Offset : Offset;
1652d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis  return Offset == 0;
1653611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner}
1654df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump