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