ARMBaseInstrInfo.cpp revision 83e0e36be8390fee1235783731f6c64aa604b7ee
1334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===- ARMBaseInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===// 2334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// 3334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// The LLVM Compiler Infrastructure 4334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// 5334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file is distributed under the University of Illinois Open Source 6334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// License. See LICENSE.TXT for details. 7334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// 8334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===// 9334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// 10334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file contains the Base ARM implementation of the TargetInstrInfo class. 11334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// 12334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===// 13334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 14334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMBaseInstrInfo.h" 15334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARM.h" 16334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMAddressingModes.h" 17334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMGenInstrInfo.inc" 18334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARMMachineFunctionInfo.h" 19334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/ADT/STLExtras.h" 20334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/LiveVariables.h" 21334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineFrameInfo.h" 22334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineInstrBuilder.h" 23334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/CodeGen/MachineJumpTableInfo.h" 24334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/Target/TargetAsmInfo.h" 25334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "llvm/Support/CommandLine.h" 26c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 27334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinusing namespace llvm; 28334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 29334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic cl::opt<bool> 30334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinEnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, 31334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin cl::desc("Enable ARM 2-addr to 3-addr conv")); 32334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 335ca53a7ad821613d324e4189ddbb0d468a326146Evan ChengARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &sti) 345ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), 355ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng STI(sti) { 36334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 37334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 38334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinMachineInstr * 39334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 40334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock::iterator &MBBI, 41334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin LiveVariables *LV) const { 42334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (!EnableARM3Addr) 43334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NULL; 44334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 45334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *MI = MBBI; 46334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineFunction &MF = *MI->getParent()->getParent(); 47334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned TSFlags = MI->getDesc().TSFlags; 48334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isPre = false; 49334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) { 50334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: return NULL; 51334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMII::IndexModePre: 52334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin isPre = true; 53334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 54334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMII::IndexModePost: 55334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 56334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 57334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 58334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Try splitting an indexed load/store to an un-indexed one plus an add/sub 59334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // operation. 60334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned MemOpc = getUnindexedOpcode(MI->getOpcode()); 61334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MemOpc == 0) 62334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NULL; 63334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 64334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *UpdateMI = NULL; 65334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *MemMI = NULL; 66334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); 67334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetInstrDesc &TID = MI->getDesc(); 68334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned NumOps = TID.getNumOperands(); 69334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isLoad = !TID.mayStore(); 70334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); 71334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineOperand &Base = MI->getOperand(2); 72334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineOperand &Offset = MI->getOperand(NumOps-3); 73334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned WBReg = WB.getReg(); 74334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned BaseReg = Base.getReg(); 75334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned OffReg = Offset.getReg(); 76334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned OffImm = MI->getOperand(NumOps-2).getImm(); 77334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm(); 78334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch (AddrMode) { 79334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: 80334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(false && "Unknown indexed op!"); 81334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NULL; 82334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMII::AddrMode2: { 83334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; 84334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Amt = ARM_AM::getAM2Offset(OffImm); 85334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (OffReg == 0) { 86e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng if (ARM_AM::getSOImmVal(Amt) == -1) 87334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Can't encode it in a so_imm operand. This transformation will 88334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // add more than 1 instruction. Abandon! 89334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NULL; 90334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI = BuildMI(MF, MI->getDebugLoc(), 91334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(isSub ? getOpcode(ARMII::SUBri) : 92334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getOpcode(ARMII::ADDri)), WBReg) 93e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng .addReg(BaseReg).addImm(Amt) 94334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Pred).addReg(0).addReg(0); 95334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else if (Amt != 0) { 96334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); 97334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); 98334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI = BuildMI(MF, MI->getDebugLoc(), 99334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(isSub ? getOpcode(ARMII::SUBrs) : 100334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getOpcode(ARMII::ADDrs)), WBReg) 101334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) 102334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Pred).addReg(0).addReg(0); 103334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else 104334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI = BuildMI(MF, MI->getDebugLoc(), 105334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(isSub ? getOpcode(ARMII::SUBrr) : 106334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getOpcode(ARMII::ADDrr)), WBReg) 107334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addReg(OffReg) 108334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Pred).addReg(0).addReg(0); 109334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 110334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 111334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMII::AddrMode3 : { 112334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub; 113334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Amt = ARM_AM::getAM3Offset(OffImm); 114334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (OffReg == 0) 115334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand. 116334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI = BuildMI(MF, MI->getDebugLoc(), 117334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(isSub ? getOpcode(ARMII::SUBri) : 118334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getOpcode(ARMII::ADDri)), WBReg) 119334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addImm(Amt) 120334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Pred).addReg(0).addReg(0); 121334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else 122334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI = BuildMI(MF, MI->getDebugLoc(), 123334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(isSub ? getOpcode(ARMII::SUBrr) : 124334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getOpcode(ARMII::ADDrr)), WBReg) 125334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addReg(OffReg) 126334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Pred).addReg(0).addReg(0); 127334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 128334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 129334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 130334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 131334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin std::vector<MachineInstr*> NewMIs; 132334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (isPre) { 133334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (isLoad) 134334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MemMI = BuildMI(MF, MI->getDebugLoc(), 135334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(MemOpc), MI->getOperand(0).getReg()) 136334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 137334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else 138334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MemMI = BuildMI(MF, MI->getDebugLoc(), 139334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(MemOpc)).addReg(MI->getOperand(1).getReg()) 140334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 141334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin NewMIs.push_back(MemMI); 142334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin NewMIs.push_back(UpdateMI); 143334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { 144334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (isLoad) 145334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MemMI = BuildMI(MF, MI->getDebugLoc(), 146334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(MemOpc), MI->getOperand(0).getReg()) 147334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 148334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else 149334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MemMI = BuildMI(MF, MI->getDebugLoc(), 150334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin get(MemOpc)).addReg(MI->getOperand(1).getReg()) 151334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 152334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (WB.isDead()) 153334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin UpdateMI->getOperand(0).setIsDead(); 154334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin NewMIs.push_back(UpdateMI); 155334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin NewMIs.push_back(MemMI); 156334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 157334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 158334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Transfer LiveVariables states, kill / dead info. 159334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (LV) { 160334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 161334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineOperand &MO = MI->getOperand(i); 162334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MO.isReg() && MO.getReg() && 163334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 164334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Reg = MO.getReg(); 165334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 166334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); 167334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MO.isDef()) { 168334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI; 169334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MO.isDead()) 170334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin LV->addVirtualRegisterDead(Reg, NewMI); 171334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 172334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MO.isUse() && MO.isKill()) { 173334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin for (unsigned j = 0; j < 2; ++j) { 174334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Look at the two new MI's in reverse order. 175334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *NewMI = NewMIs[j]; 176334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (!NewMI->readsRegister(Reg)) 177334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin continue; 178334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin LV->addVirtualRegisterKilled(Reg, NewMI); 179334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (VI.removeKill(MI)) 180334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin VI.Kills.push_back(NewMI); 181334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 182334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 183334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 184334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 185334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 186334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 187334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 188334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MFI->insert(MBBI, NewMIs[1]); 189334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MFI->insert(MBBI, NewMIs[0]); 190334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NewMIs[0]; 191334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 192334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 193334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// Branch analysis. 194334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool 195334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 196334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock *&FBB, 197334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin SmallVectorImpl<MachineOperand> &Cond, 198334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool AllowModify) const { 199334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If the block has no terminators, it just falls into the block after it. 200334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock::iterator I = MBB.end(); 201334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 202334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 203334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 204334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Get the last instruction in the block. 205334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *LastInst = I; 206334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 207334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If there is only one terminator instruction, process it. 208334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned LastOpc = LastInst->getOpcode(); 209334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 2105ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (isUncondBranchOpcode(LastOpc)) { 211334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin TBB = LastInst->getOperand(0).getMBB(); 212334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 213334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 2145ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (isCondBranchOpcode(LastOpc)) { 215334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Block ends with fall-through condbranch. 216334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin TBB = LastInst->getOperand(0).getMBB(); 217334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Cond.push_back(LastInst->getOperand(1)); 218334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Cond.push_back(LastInst->getOperand(2)); 219334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 220334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 221334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; // Can't handle indirect branch. 222334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 223334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 224334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Get the instruction before it if it is a terminator. 225334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *SecondLastInst = I; 226334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 227334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If there are three terminators, we don't know what sort of block this is. 228334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 229334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 230334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 2315ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng // If the block ends with a B and a Bcc, handle it. 232334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SecondLastOpc = SecondLastInst->getOpcode(); 2335ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 234334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin TBB = SecondLastInst->getOperand(0).getMBB(); 235334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Cond.push_back(SecondLastInst->getOperand(1)); 236334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Cond.push_back(SecondLastInst->getOperand(2)); 237334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin FBB = LastInst->getOperand(0).getMBB(); 238334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 239334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 240334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 241334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If the block ends with two unconditional branches, handle it. The second 242334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // one is not executed, so remove it. 2435ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 244334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin TBB = SecondLastInst->getOperand(0).getMBB(); 245334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I = LastInst; 246334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (AllowModify) 247334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I->eraseFromParent(); 248334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 249334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 250334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 251334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // ...likewise if it ends with a branch table followed by an unconditional 252334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // branch. The branch folder can create these, and we must get rid of them for 253334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // correctness of Thumb constant islands. 25483e0e36be8390fee1235783731f6c64aa604b7eeEvan Cheng if (isJumpTableBranchOpcode(SecondLastOpc) && 2555ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng isUncondBranchOpcode(LastOpc)) { 256334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I = LastInst; 257334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (AllowModify) 258334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I->eraseFromParent(); 259334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 260334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 261334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 262334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Otherwise, can't handle this. 263334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 264334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 265334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 266334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 267334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 268334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock::iterator I = MBB.end(); 269334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I == MBB.begin()) return 0; 270334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin --I; 2715ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (!isUncondBranchOpcode(I->getOpcode()) && 2725ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng !isCondBranchOpcode(I->getOpcode())) 273334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 274334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 275334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Remove the branch. 276334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I->eraseFromParent(); 277334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 278334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I = MBB.end(); 279334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 280334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I == MBB.begin()) return 1; 281334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin --I; 2825ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (!isCondBranchOpcode(I->getOpcode())) 283334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 1; 284334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 285334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Remove the branch. 286334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin I->eraseFromParent(); 287334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 2; 288334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 289334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 290334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned 291334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 292334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock *FBB, 293334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<MachineOperand> &Cond) const { 294334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // FIXME this should probably have a DebugLoc argument 295334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DebugLoc dl = DebugLoc::getUnknownLoc(); 2965ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng int BOpc = !STI.isThumb() 2975ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng ? ARM::B : (STI.isThumb2() ? ARM::t2B : ARM::tB); 2985ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng int BccOpc = !STI.isThumb() 2995ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng ? ARM::Bcc : (STI.isThumb2() ? ARM::t2Bcc : ARM::tBcc); 300334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 301334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Shouldn't be a fall through. 302334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 303334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert((Cond.size() == 2 || Cond.size() == 0) && 304334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin "ARM branch conditions have two components!"); 305334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 306334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (FBB == 0) { 307334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (Cond.empty()) // Unconditional branch? 308334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB); 309334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else 310334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 311334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 312334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 1; 313334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 314334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 315334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Two-way conditional branch. 316334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 317334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 318334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB); 319334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 2; 320334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 321334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 322334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo:: 323334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 324334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm(); 325334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Cond[0].setImm(ARMCC::getOppositeCondition(CC)); 326334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 327334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 328334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 329334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo:: 330334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinPredicateInstruction(MachineInstr *MI, 331334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<MachineOperand> &Pred) const { 332334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Opc = MI->getOpcode(); 3335ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (isUncondBranchOpcode(Opc)) { 3345ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng MI->setDesc(get(getMatchingCondBranchOpcode(Opc))); 335334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm())); 336334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false)); 337334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 338334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 339334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 340334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin int PIdx = MI->findFirstPredOperandIdx(); 341334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (PIdx != -1) { 342334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineOperand &PMO = MI->getOperand(PIdx); 343334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin PMO.setImm(Pred[0].getImm()); 344334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(PIdx+1).setReg(Pred[1].getReg()); 345334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 346334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 347334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 348334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 349334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 350334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo:: 351334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinSubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 352334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<MachineOperand> &Pred2) const { 353334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (Pred1.size() > 2 || Pred2.size() > 2) 354334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 355334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 356334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm(); 357334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm(); 358334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (CC1 == CC2) 359334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 360334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 361334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch (CC1) { 362334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: 363334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 364334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMCC::AL: 365334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 366334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMCC::HS: 367334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return CC2 == ARMCC::HI; 368334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMCC::LS: 369334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return CC2 == ARMCC::LO || CC2 == ARMCC::EQ; 370334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMCC::GE: 371334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return CC2 == ARMCC::GT; 372334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMCC::LE: 373334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return CC2 == ARMCC::LT; 374334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 375334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 376334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 377334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, 378334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin std::vector<MachineOperand> &Pred) const { 379334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetInstrDesc &TID = MI->getDesc(); 380334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) 381334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 382334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 383334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool Found = false; 384334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 385334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineOperand &MO = MI->getOperand(i); 386334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MO.isReg() && MO.getReg() == ARM::CPSR) { 387334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Pred.push_back(MO); 388334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin Found = true; 389334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 390334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 391334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 392334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return Found; 393334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 394334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 395334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 396334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing 397334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 398334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned JTI) DISABLE_INLINE; 399334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 400334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned JTI) { 401334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return JT[JTI].MBBs.size(); 402334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 403334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 404334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// GetInstSize - Return the size of the specified MachineInstr. 405334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// 406334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 407334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineBasicBlock &MBB = *MI->getParent(); 408334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineFunction *MF = MBB.getParent(); 409334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo(); 410334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 411334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Basic size info comes from the TSFlags field. 412334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetInstrDesc &TID = MI->getDesc(); 413334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned TSFlags = TID.TSFlags; 414334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 415334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) { 416334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: { 417334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If this machine instr is an inline asm, measure it. 418334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->getOpcode() == ARM::INLINEASM) 419334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName()); 420334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->isLabel()) 421334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 422334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch (MI->getOpcode()) { 423334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: 424c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown or unset size field for instr!"); 425334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case TargetInstrInfo::IMPLICIT_DEF: 426334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case TargetInstrInfo::DECLARE: 427334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case TargetInstrInfo::DBG_LABEL: 428334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case TargetInstrInfo::EH_LABEL: 429334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 430334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 431334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin break; 432334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 433789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng case ARMII::Size8Bytes: return 8; // ARM instruction x 2. 434789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction. 435789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng case ARMII::Size2Bytes: return 2; // Thumb1 instruction. 436334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARMII::SizeSpecial: { 437789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng bool IsThumb1JT = false; 438334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin switch (MI->getOpcode()) { 439334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARM::CONSTPOOL_ENTRY: 440334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If this machine instr is a constant pool entry, its size is recorded as 441334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // operand #2. 442334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return MI->getOperand(2).getImm(); 443789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng case ARM::Int_eh_sjlj_setjmp: 444789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng return 12; 445789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng case ARM::tBR_JTr: 446789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng IsThumb1JT = true; 447789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng // Fallthrough 448334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARM::BR_JTr: 449334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARM::BR_JTm: 450334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin case ARM::BR_JTadd: 45166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng case ARM::t2BR_JT: { 452334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // These are jumptable branches, i.e. a branch followed by an inlined 453334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // jumptable. The size is 4 + 4 * number of entries. 454334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned NumOps = TID.getNumOperands(); 455334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineOperand JTOP = 456334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2)); 457334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned JTI = JTOP.getIndex(); 458334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 459334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 460334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(JTI < JT.size()); 461334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Thumb instructions are 2 byte aligned, but JT entries are 4 byte 462334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // 4 aligned. The assembler / linker may add 2 byte padding just before 463334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // the JT entries. The size does not include this padding; the 464334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // constant islands pass does separate bookkeeping for it. 465334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // FIXME: If we know the size of the function is less than (1 << 16) *2 466334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // bytes, we can use 16-bit entries instead. Then there won't be an 467334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // alignment issue. 468789476240d6b6f8ad9366cadf790a82bd41bb0b3Evan Cheng return getNumJTEntries(JT, JTI) * 4 + (IsThumb1JT ? 2 : 4); 469334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 470334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin default: 471334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Otherwise, pseudo-instruction sizes are zero. 472334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 473334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 474334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 475334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 476334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; // Not reached 477334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 478334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 479334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// Return true if the instruction is a register to register move and 480334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// leave the source and dest operands in the passed parameters. 481334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin/// 482334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool 483334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI, 484334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned &SrcReg, unsigned &DstReg, 485334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned& SrcSubIdx, unsigned& DstSubIdx) const { 486334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin SrcSubIdx = DstSubIdx = 0; // No sub-registers. 487334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 48868e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng switch (MI.getOpcode()) { 489dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng default: break; 49068e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::FCPYS: 49168e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::FCPYD: 49268e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::VMOVD: 49368e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::VMOVQ: { 494334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin SrcReg = MI.getOperand(1).getReg(); 495334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DstReg = MI.getOperand(0).getReg(); 496334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 497334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 49868e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::MOVr: 49968e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::tMOVr: 50068e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::tMOVgpr2tgpr: 50168e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::tMOVtgpr2gpr: 50268e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::tMOVgpr2gpr: 50368e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng case ARM::t2MOVr: { 504334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(MI.getDesc().getNumOperands() >= 2 && 505334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI.getOperand(0).isReg() && 506334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI.getOperand(1).isReg() && 507334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin "Invalid ARM MOV instruction"); 508334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin SrcReg = MI.getOperand(1).getReg(); 509334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DstReg = MI.getOperand(0).getReg(); 510334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 511334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 51268e3c6ae49ff67cba98403e43b5bd0c2499caa41Evan Cheng } 513334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 514334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 515334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 516334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 517334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned 518334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 519334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin int &FrameIndex) const { 520dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng switch (MI->getOpcode()) { 521dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng default: break; 522dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::LDR: 523dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame. 524334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->getOperand(1).isFI() && 525334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).isReg() && 526334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(3).isImm() && 527334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).getReg() == 0 && 528334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(3).getImm() == 0) { 529334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin FrameIndex = MI->getOperand(1).getIndex(); 530334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return MI->getOperand(0).getReg(); 531334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 532dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 533dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::t2LDRi12: 534dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::tRestore: 5355ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin if (MI->getOperand(1).isFI() && 5365ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MI->getOperand(2).isImm() && 5375ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MI->getOperand(2).getImm() == 0) { 5385ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin FrameIndex = MI->getOperand(1).getIndex(); 5395ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin return MI->getOperand(0).getReg(); 5405ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin } 541dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 542dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::FLDD: 543dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::FLDS: 544334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->getOperand(1).isFI() && 545334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).isImm() && 546334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).getImm() == 0) { 547334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin FrameIndex = MI->getOperand(1).getIndex(); 548334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return MI->getOperand(0).getReg(); 549334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 550dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 551334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 552334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 553334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 554334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 555334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 556334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinunsigned 557334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 558334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin int &FrameIndex) const { 559dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng switch (MI->getOpcode()) { 560dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng default: break; 561dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::STR: 562dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::t2STRs: // FIXME: don't use t2STRs to access frame. 563334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->getOperand(1).isFI() && 564334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).isReg() && 565334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(3).isImm() && 566334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).getReg() == 0 && 567334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(3).getImm() == 0) { 568334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin FrameIndex = MI->getOperand(1).getIndex(); 569334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return MI->getOperand(0).getReg(); 570334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 571dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 572dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::t2STRi12: 573dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::tSpill: 5745ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin if (MI->getOperand(1).isFI() && 5755ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MI->getOperand(2).isImm() && 5765ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MI->getOperand(2).getImm() == 0) { 5775ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin FrameIndex = MI->getOperand(1).getIndex(); 5785ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin return MI->getOperand(0).getReg(); 5795ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin } 580dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 581dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::FSTD: 582dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng case ARM::FSTS: 583334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (MI->getOperand(1).isFI() && 584334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).isImm() && 585334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MI->getOperand(2).getImm() == 0) { 586334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin FrameIndex = MI->getOperand(1).getIndex(); 587334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return MI->getOperand(0).getReg(); 588334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 589dced03fc846fa7cd9558ecb8e33ca98ec29bdcf0Evan Cheng break; 590334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 591334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 592334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 593334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 594334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 595334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool 596334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 597334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineBasicBlock::iterator I, 598334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned DestReg, unsigned SrcReg, 599334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetRegisterClass *DestRC, 600334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetRegisterClass *SrcRC) const { 601334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DebugLoc DL = DebugLoc::getUnknownLoc(); 602334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I != MBB.end()) DL = I->getDebugLoc(); 603334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 604334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (DestRC != SrcRC) { 605334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // Not yet supported! 606334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 607334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 608334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 609334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (DestRC == ARM::GPRRegisterClass) 61008b93c6a70ae59af375f205cfcffeaa3517577abEvan Cheng AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), 611dd6f63209cba0003e67470938830de2cb6917336Evan Cheng DestReg).addReg(SrcReg))); 612334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else if (DestRC == ARM::SPRRegisterClass) 613b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg) 614334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg)); 615334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else if (DestRC == ARM::DPRRegisterClass) 616b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) 617334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg)); 618334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else if (DestRC == ARM::QPRRegisterClass) 619b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); 620334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin else 621334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 622334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 623334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 624334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 625334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 626334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinvoid ARMBaseInstrInfo:: 627334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 628334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SrcReg, bool isKill, int FI, 629334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetRegisterClass *RC) const { 630334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DebugLoc DL = DebugLoc::getUnknownLoc(); 631334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I != MBB.end()) DL = I->getDebugLoc(); 632334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 633334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (RC == ARM::GPRRegisterClass) { 6345732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) 635334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg, getKillRegState(isKill)) 636334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addReg(0).addImm(0)); 637334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else if (RC == ARM::DPRRegisterClass) { 638b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) 639334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg, getKillRegState(isKill)) 640334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0)); 641334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { 642334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 643b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS)) 644334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg, getKillRegState(isKill)) 645334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0)); 646334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 647334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 648334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 649334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinvoid ARMBaseInstrInfo:: 650334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 651334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned DestReg, int FI, 652334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const TargetRegisterClass *RC) const { 653334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin DebugLoc DL = DebugLoc::getUnknownLoc(); 654334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (I != MBB.end()) DL = I->getDebugLoc(); 655334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 656334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (RC == ARM::GPRRegisterClass) { 6575732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) 658334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addReg(0).addImm(0)); 659334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else if (RC == ARM::DPRRegisterClass) { 660b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) 661334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0)); 662334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { 663334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 664b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg) 665334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0)); 666334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 667334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 668334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 669334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinMachineInstr *ARMBaseInstrInfo:: 670334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinfoldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 671334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<unsigned> &Ops, int FI) const { 672334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (Ops.size() != 1) return NULL; 673334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 674334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned OpNum = Ops[0]; 675334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Opc = MI->getOpcode(); 676334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr *NewMI = NULL; 6775732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 678334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If it is updating CPSR, then it cannot be folded. 6791f5c9887544ac2cb39d48e35cc6fa7a7b73ed3b0Evan Cheng if (MI->getOperand(4).getReg() != ARM::CPSR || MI->getOperand(4).isDead()) { 680334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Pred = MI->getOperand(2).getImm(); 681334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned PredReg = MI->getOperand(3).getReg(); 682334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (OpNum == 0) { // move -> store 683334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SrcReg = MI->getOperand(1).getReg(); 684334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isKill = MI->getOperand(1).isKill(); 685334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(1).isUndef(); 6865732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng if (Opc == ARM::MOVr) 6875732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) 6885732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 6895732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 6905732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng else // ARM::t2MOVr 6915732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12)) 6925732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 6935732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 694334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { // move -> load 695334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned DstReg = MI->getOperand(0).getReg(); 696334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isDead = MI->getOperand(0).isDead(); 697334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(0).isUndef(); 6985732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng if (Opc == ARM::MOVr) 6995732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) 7005732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addReg(DstReg, 7015732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng RegState::Define | 7025732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng getDeadRegState(isDead) | 7035732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng getUndefRegState(isUndef)) 7045732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 7055732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng else // ARM::t2MOVr 7065732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12)) 7075732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addReg(DstReg, 7085732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng RegState::Define | 7095732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng getDeadRegState(isDead) | 7105732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng getUndefRegState(isUndef)) 7115732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 712334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 713334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 714334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 715b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng else if (Opc == ARM::FCPYS) { 716334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Pred = MI->getOperand(2).getImm(); 717334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned PredReg = MI->getOperand(3).getReg(); 718334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (OpNum == 0) { // move -> store 719334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SrcReg = MI->getOperand(1).getReg(); 720334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isKill = MI->getOperand(1).isKill(); 721334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(1).isUndef(); 722b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS)) 723334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 724334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI) 725334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addImm(0).addImm(Pred).addReg(PredReg); 726334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { // move -> load 727334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned DstReg = MI->getOperand(0).getReg(); 728334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isDead = MI->getOperand(0).isDead(); 729334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(0).isUndef(); 730b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS)) 731334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(DstReg, 732334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin RegState::Define | 733334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getDeadRegState(isDead) | 734334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getUndefRegState(isUndef)) 735334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 736334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 737334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 738b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng else if (Opc == ARM::FCPYD) { 739334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Pred = MI->getOperand(2).getImm(); 740334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned PredReg = MI->getOperand(3).getReg(); 741334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (OpNum == 0) { // move -> store 742334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned SrcReg = MI->getOperand(1).getReg(); 743334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isKill = MI->getOperand(1).isKill(); 744334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(1).isUndef(); 745b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD)) 746334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 747334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 748334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } else { // move -> load 749334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned DstReg = MI->getOperand(0).getReg(); 750334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isDead = MI->getOperand(0).isDead(); 751334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin bool isUndef = MI->getOperand(0).isUndef(); 752b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD)) 753334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addReg(DstReg, 754334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin RegState::Define | 755334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getDeadRegState(isDead) | 756334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin getUndefRegState(isUndef)) 757334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 758334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 759334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 760334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 761334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return NewMI; 762334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 763334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 764334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinMachineInstr* 765334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 766334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr* MI, 767334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<unsigned> &Ops, 768334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin MachineInstr* LoadMI) const { 7691f5c9887544ac2cb39d48e35cc6fa7a7b73ed3b0Evan Cheng // FIXME 770334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 771334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 772334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 773334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool 774334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid GoodwinARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, 775334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin const SmallVectorImpl<unsigned> &Ops) const { 776334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin if (Ops.size() != 1) return false; 777334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 778334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin unsigned Opc = MI->getOpcode(); 7795732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 780334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // If it is updating CPSR, then it cannot be folded. 7811f5c9887544ac2cb39d48e35cc6fa7a7b73ed3b0Evan Cheng return MI->getOperand(4).getReg() != ARM::CPSR ||MI->getOperand(4).isDead(); 782b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) { 783334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return true; 784b74bb1a7a471a77e793d90de158aa4bbc67fe94dEvan Cheng } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) { 785334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; // FIXME 786334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin } 787334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 788334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return false; 789334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 7905ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng 7915ca53a7ad821613d324e4189ddbb0d468a326146Evan Chengint ARMBaseInstrInfo::getMatchingCondBranchOpcode(int Opc) const { 7925ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng if (Opc == ARM::B) 7935ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng return ARM::Bcc; 7945ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng else if (Opc == ARM::tB) 7955ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng return ARM::tBcc; 7965ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng else if (Opc == ARM::t2B) 7975ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng return ARM::t2Bcc; 7985ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng 7995ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng llvm_unreachable("Unknown unconditional branch opcode!"); 8005ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng return 0; 8015ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng} 8025ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng 803