ARMBaseInstrInfo.cpp revision 201360
1109864Sjeff//===- ARMBaseInstrInfo.cpp - ARM Instruction Information -------*- C++ -*-===// 2113357Sjeff// 3109864Sjeff// The LLVM Compiler Infrastructure 4109864Sjeff// 5109864Sjeff// This file is distributed under the University of Illinois Open Source 6109864Sjeff// License. See LICENSE.TXT for details. 7109864Sjeff// 8109864Sjeff//===----------------------------------------------------------------------===// 9109864Sjeff// 10109864Sjeff// This file contains the Base ARM implementation of the TargetInstrInfo class. 11109864Sjeff// 12109864Sjeff//===----------------------------------------------------------------------===// 13109864Sjeff 14109864Sjeff#include "ARMBaseInstrInfo.h" 15109864Sjeff#include "ARM.h" 16109864Sjeff#include "ARMAddressingModes.h" 17109864Sjeff#include "ARMConstantPoolValue.h" 18109864Sjeff#include "ARMGenInstrInfo.inc" 19109864Sjeff#include "ARMMachineFunctionInfo.h" 20109864Sjeff#include "ARMRegisterInfo.h" 21109864Sjeff#include "llvm/Constants.h" 22109864Sjeff#include "llvm/Function.h" 23109864Sjeff#include "llvm/GlobalValue.h" 24109864Sjeff#include "llvm/ADT/STLExtras.h" 25109864Sjeff#include "llvm/CodeGen/LiveVariables.h" 26109864Sjeff#include "llvm/CodeGen/MachineConstantPool.h" 27109864Sjeff#include "llvm/CodeGen/MachineFrameInfo.h" 28109864Sjeff#include "llvm/CodeGen/MachineInstrBuilder.h" 29109864Sjeff#include "llvm/CodeGen/MachineJumpTableInfo.h" 30109864Sjeff#include "llvm/CodeGen/MachineMemOperand.h" 31109864Sjeff#include "llvm/CodeGen/PseudoSourceValue.h" 32109864Sjeff#include "llvm/MC/MCAsmInfo.h" 33109864Sjeff#include "llvm/Support/CommandLine.h" 34109864Sjeff#include "llvm/Support/Debug.h" 35109864Sjeff#include "llvm/Support/ErrorHandling.h" 36112966Sjeffusing namespace llvm; 37109864Sjeff 38109864Sjeffstatic cl::opt<bool> 39109864SjeffEnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, 40109864Sjeff cl::desc("Enable ARM 2-addr to 3-addr conv")); 41109864Sjeff 42109864SjeffARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI) 43109864Sjeff : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), 44109864Sjeff Subtarget(STI) { 45109864Sjeff} 46109864Sjeff 47109864SjeffMachineInstr * 48109864SjeffARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 49109864Sjeff MachineBasicBlock::iterator &MBBI, 50109864Sjeff LiveVariables *LV) const { 51109864Sjeff // FIXME: Thumb2 support. 52109864Sjeff 53113357Sjeff if (!EnableARM3Addr) 54113357Sjeff return NULL; 55109864Sjeff 56109864Sjeff MachineInstr *MI = MBBI; 57109864Sjeff MachineFunction &MF = *MI->getParent()->getParent(); 58109864Sjeff unsigned TSFlags = MI->getDesc().TSFlags; 59109864Sjeff bool isPre = false; 60109864Sjeff switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) { 61109864Sjeff default: return NULL; 62109864Sjeff case ARMII::IndexModePre: 63113357Sjeff isPre = true; 64113357Sjeff break; 65113357Sjeff case ARMII::IndexModePost: 66113357Sjeff break; 67113357Sjeff } 68113357Sjeff 69113357Sjeff // Try splitting an indexed load/store to an un-indexed one plus an add/sub 70113357Sjeff // operation. 71113357Sjeff unsigned MemOpc = getUnindexedOpcode(MI->getOpcode()); 72113357Sjeff if (MemOpc == 0) 73113357Sjeff return NULL; 74111857Sjeff 75113357Sjeff MachineInstr *UpdateMI = NULL; 76111857Sjeff MachineInstr *MemMI = NULL; 77109864Sjeff unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); 78109864Sjeff const TargetInstrDesc &TID = MI->getDesc(); 79109864Sjeff unsigned NumOps = TID.getNumOperands(); 80109864Sjeff bool isLoad = !TID.mayStore(); 81109864Sjeff const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); 82109864Sjeff const MachineOperand &Base = MI->getOperand(2); 83109864Sjeff const MachineOperand &Offset = MI->getOperand(NumOps-3); 84109864Sjeff unsigned WBReg = WB.getReg(); 85109864Sjeff unsigned BaseReg = Base.getReg(); 86109864Sjeff unsigned OffReg = Offset.getReg(); 87109864Sjeff unsigned OffImm = MI->getOperand(NumOps-2).getImm(); 88109864Sjeff ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm(); 89113357Sjeff switch (AddrMode) { 90110260Sjeff default: 91109864Sjeff assert(false && "Unknown indexed op!"); 92109864Sjeff return NULL; 93109864Sjeff case ARMII::AddrMode2: { 94109864Sjeff bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; 95109864Sjeff unsigned Amt = ARM_AM::getAM2Offset(OffImm); 96109864Sjeff if (OffReg == 0) { 97110260Sjeff if (ARM_AM::getSOImmVal(Amt) == -1) 98109864Sjeff // Can't encode it in a so_imm operand. This transformation will 99109864Sjeff // add more than 1 instruction. Abandon! 100110645Sjeff return NULL; 101110645Sjeff UpdateMI = BuildMI(MF, MI->getDebugLoc(), 102109864Sjeff get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) 103109864Sjeff .addReg(BaseReg).addImm(Amt) 104110645Sjeff .addImm(Pred).addReg(0).addReg(0); 105109864Sjeff } else if (Amt != 0) { 106109864Sjeff ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); 107109864Sjeff unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); 108109864Sjeff UpdateMI = BuildMI(MF, MI->getDebugLoc(), 109109864Sjeff get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg) 110109864Sjeff .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) 111110267Sjeff .addImm(Pred).addReg(0).addReg(0); 112109864Sjeff } else 113109864Sjeff UpdateMI = BuildMI(MF, MI->getDebugLoc(), 114109864Sjeff get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) 115109864Sjeff .addReg(BaseReg).addReg(OffReg) 116109864Sjeff .addImm(Pred).addReg(0).addReg(0); 117109864Sjeff break; 118109864Sjeff } 119109864Sjeff case ARMII::AddrMode3 : { 120109864Sjeff bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub; 121109864Sjeff unsigned Amt = ARM_AM::getAM3Offset(OffImm); 122109864Sjeff if (OffReg == 0) 123111857Sjeff // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand. 124111857Sjeff UpdateMI = BuildMI(MF, MI->getDebugLoc(), 125111857Sjeff get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) 126111857Sjeff .addReg(BaseReg).addImm(Amt) 127111857Sjeff .addImm(Pred).addReg(0).addReg(0); 128111857Sjeff else 129109864Sjeff UpdateMI = BuildMI(MF, MI->getDebugLoc(), 130111857Sjeff get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) 131112966Sjeff .addReg(BaseReg).addReg(OffReg) 132112970Sjeff .addImm(Pred).addReg(0).addReg(0); 133113357Sjeff break; 134111857Sjeff } 135111857Sjeff } 136113357Sjeff 137113357Sjeff std::vector<MachineInstr*> NewMIs; 138109864Sjeff if (isPre) { 139109864Sjeff if (isLoad) 140111857Sjeff MemMI = BuildMI(MF, MI->getDebugLoc(), 141109864Sjeff get(MemOpc), MI->getOperand(0).getReg()) 142110645Sjeff .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 143110645Sjeff else 144111857Sjeff MemMI = BuildMI(MF, MI->getDebugLoc(), 145111857Sjeff get(MemOpc)).addReg(MI->getOperand(1).getReg()) 146111857Sjeff .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 147111857Sjeff NewMIs.push_back(MemMI); 148109864Sjeff NewMIs.push_back(UpdateMI); 149113357Sjeff } else { 150110645Sjeff if (isLoad) 151111857Sjeff MemMI = BuildMI(MF, MI->getDebugLoc(), 152111857Sjeff get(MemOpc), MI->getOperand(0).getReg()) 153111857Sjeff .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 154111857Sjeff else 155109864Sjeff MemMI = BuildMI(MF, MI->getDebugLoc(), 156109864Sjeff get(MemOpc)).addReg(MI->getOperand(1).getReg()) 157109864Sjeff .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 158109864Sjeff if (WB.isDead()) 159109864Sjeff UpdateMI->getOperand(0).setIsDead(); 160109864Sjeff NewMIs.push_back(UpdateMI); 161109864Sjeff NewMIs.push_back(MemMI); 162112966Sjeff } 163112966Sjeff 164109864Sjeff // Transfer LiveVariables states, kill / dead info. 165113357Sjeff if (LV) { 166113357Sjeff for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 167111857Sjeff MachineOperand &MO = MI->getOperand(i); 168109864Sjeff if (MO.isReg() && MO.getReg() && 169112966Sjeff TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 170113357Sjeff unsigned Reg = MO.getReg(); 171109864Sjeff 172109864Sjeff LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); 173109864Sjeff if (MO.isDef()) { 174109864Sjeff MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI; 175110645Sjeff if (MO.isDead()) 176110645Sjeff LV->addVirtualRegisterDead(Reg, NewMI); 177109864Sjeff } 178113357Sjeff if (MO.isUse() && MO.isKill()) { 179113357Sjeff for (unsigned j = 0; j < 2; ++j) { 180113357Sjeff // Look at the two new MI's in reverse order. 181113357Sjeff MachineInstr *NewMI = NewMIs[j]; 182113357Sjeff if (!NewMI->readsRegister(Reg)) 183113357Sjeff continue; 184109864Sjeff LV->addVirtualRegisterKilled(Reg, NewMI); 185109864Sjeff if (VI.removeKill(MI)) 186109864Sjeff VI.Kills.push_back(NewMI); 187109864Sjeff break; 188109864Sjeff } 189109864Sjeff } 190109864Sjeff } 191109864Sjeff } 192112971Sjeff } 193109864Sjeff 194109864Sjeff MFI->insert(MBBI, NewMIs[1]); 195109864Sjeff MFI->insert(MBBI, NewMIs[0]); 196113357Sjeff return NewMIs[0]; 197109864Sjeff} 198109864Sjeff 199113357Sjeff// Branch analysis. 200113357Sjeffbool 201109864SjeffARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 202113357Sjeff MachineBasicBlock *&FBB, 203113357Sjeff SmallVectorImpl<MachineOperand> &Cond, 204113357Sjeff bool AllowModify) const { 205113357Sjeff // If the block has no terminators, it just falls into the block after it. 206113357Sjeff MachineBasicBlock::iterator I = MBB.end(); 207113357Sjeff if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 208113357Sjeff return false; 209113357Sjeff 210110267Sjeff // Get the last instruction in the block. 211110267Sjeff MachineInstr *LastInst = I; 212110267Sjeff 213109864Sjeff // If there is only one terminator instruction, process it. 214109864Sjeff unsigned LastOpc = LastInst->getOpcode(); 215109864Sjeff if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 216109864Sjeff if (isUncondBranchOpcode(LastOpc)) { 217109864Sjeff TBB = LastInst->getOperand(0).getMBB(); 218110028Sjeff return false; 219109864Sjeff } 220110028Sjeff if (isCondBranchOpcode(LastOpc)) { 221110028Sjeff // Block ends with fall-through condbranch. 222110028Sjeff TBB = LastInst->getOperand(0).getMBB(); 223110028Sjeff Cond.push_back(LastInst->getOperand(1)); 224110028Sjeff Cond.push_back(LastInst->getOperand(2)); 225110028Sjeff return false; 226110028Sjeff } 227109864Sjeff return true; // Can't handle indirect branch. 228112966Sjeff } 229113357Sjeff 230111857Sjeff // Get the instruction before it if it is a terminator. 231109864Sjeff MachineInstr *SecondLastInst = I; 232109864Sjeff 233109864Sjeff // If there are three terminators, we don't know what sort of block this is. 234110267Sjeff if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 235110028Sjeff return true; 236110028Sjeff 237112994Sjeff // If the block ends with a B and a Bcc, handle it. 238113357Sjeff unsigned SecondLastOpc = SecondLastInst->getOpcode(); 239113357Sjeff if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 240113357Sjeff TBB = SecondLastInst->getOperand(0).getMBB(); 241113357Sjeff Cond.push_back(SecondLastInst->getOperand(1)); 242110267Sjeff Cond.push_back(SecondLastInst->getOperand(2)); 243110267Sjeff FBB = LastInst->getOperand(0).getMBB(); 244110267Sjeff return false; 245110028Sjeff } 246113357Sjeff 247113357Sjeff // If the block ends with two unconditional branches, handle it. The second 248110267Sjeff // one is not executed, so remove it. 249113357Sjeff if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 250112994Sjeff TBB = SecondLastInst->getOperand(0).getMBB(); 251113357Sjeff I = LastInst; 252113357Sjeff if (AllowModify) 253112994Sjeff I->eraseFromParent(); 254113357Sjeff return false; 255113357Sjeff } 256113357Sjeff 257113357Sjeff // ...likewise if it ends with a branch table followed by an unconditional 258113357Sjeff // branch. The branch folder can create these, and we must get rid of them for 259113357Sjeff // correctness of Thumb constant islands. 260113357Sjeff if ((isJumpTableBranchOpcode(SecondLastOpc) || 261113357Sjeff isIndirectBranchOpcode(SecondLastOpc)) && 262113357Sjeff isUncondBranchOpcode(LastOpc)) { 263113357Sjeff I = LastInst; 264113357Sjeff if (AllowModify) 265113357Sjeff I->eraseFromParent(); 266113357Sjeff return true; 267112994Sjeff } 268113357Sjeff 269113357Sjeff // Otherwise, can't handle this. 270113357Sjeff return true; 271113357Sjeff} 272113357Sjeff 273113357Sjeff 274113357Sjeffunsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 275113357Sjeff MachineBasicBlock::iterator I = MBB.end(); 276113357Sjeff if (I == MBB.begin()) return 0; 277113357Sjeff --I; 278113357Sjeff if (!isUncondBranchOpcode(I->getOpcode()) && 279110267Sjeff !isCondBranchOpcode(I->getOpcode())) 280110267Sjeff return 0; 281110267Sjeff 282110267Sjeff // Remove the branch. 283113357Sjeff I->eraseFromParent(); 284112994Sjeff 285110267Sjeff I = MBB.end(); 286110267Sjeff 287113357Sjeff if (I == MBB.begin()) return 1; 288113357Sjeff --I; 289113357Sjeff if (!isCondBranchOpcode(I->getOpcode())) 290113357Sjeff return 1; 291113357Sjeff 292110267Sjeff // Remove the branch. 293110267Sjeff I->eraseFromParent(); 294110267Sjeff return 2; 295110267Sjeff} 296110267Sjeff 297113357Sjeffunsigned 298113357SjeffARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 299110267Sjeff MachineBasicBlock *FBB, 300113357Sjeff const SmallVectorImpl<MachineOperand> &Cond) const { 301113357Sjeff // FIXME this should probably have a DebugLoc argument 302113357Sjeff DebugLoc dl = DebugLoc::getUnknownLoc(); 303113357Sjeff 304110267Sjeff ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>(); 305110267Sjeff int BOpc = !AFI->isThumbFunction() 306113357Sjeff ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB); 307113357Sjeff int BccOpc = !AFI->isThumbFunction() 308110267Sjeff ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc); 309113357Sjeff 310113357Sjeff // Shouldn't be a fall through. 311113357Sjeff assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 312113357Sjeff assert((Cond.size() == 2 || Cond.size() == 0) && 313113357Sjeff "ARM branch conditions have two components!"); 314113357Sjeff 315113357Sjeff if (FBB == 0) { 316113357Sjeff if (Cond.empty()) // Unconditional branch? 317113357Sjeff BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB); 318113357Sjeff else 319113357Sjeff BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 320113357Sjeff .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 321113357Sjeff return 1; 322113357Sjeff } 323113357Sjeff 324113357Sjeff // Two-way conditional branch. 325113357Sjeff BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 326113357Sjeff .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 327113357Sjeff BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB); 328113357Sjeff return 2; 329113357Sjeff} 330113357Sjeff 331110267Sjeffbool ARMBaseInstrInfo:: 332110267SjeffReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 333113357Sjeff ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm(); 334110267Sjeff Cond[0].setImm(ARMCC::getOppositeCondition(CC)); 335110267Sjeff return false; 336110267Sjeff} 337110267Sjeff 338110267Sjeffbool ARMBaseInstrInfo:: 339110267SjeffPredicateInstruction(MachineInstr *MI, 340110267Sjeff const SmallVectorImpl<MachineOperand> &Pred) const { 341110267Sjeff unsigned Opc = MI->getOpcode(); 342110267Sjeff if (isUncondBranchOpcode(Opc)) { 343110267Sjeff MI->setDesc(get(getMatchingCondBranchOpcode(Opc))); 344110267Sjeff MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm())); 345110267Sjeff MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false)); 346110267Sjeff return true; 347110267Sjeff } 348110267Sjeff 349113357Sjeff int PIdx = MI->findFirstPredOperandIdx(); 350113357Sjeff if (PIdx != -1) { 351110267Sjeff MachineOperand &PMO = MI->getOperand(PIdx); 352110267Sjeff PMO.setImm(Pred[0].getImm()); 353110267Sjeff MI->getOperand(PIdx+1).setReg(Pred[1].getReg()); 354113371Sjeff return true; 355110267Sjeff } 356110267Sjeff return false; 357110267Sjeff} 358110267Sjeff 359110267Sjeffbool ARMBaseInstrInfo:: 360110267SjeffSubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 361110267Sjeff const SmallVectorImpl<MachineOperand> &Pred2) const { 362110267Sjeff if (Pred1.size() > 2 || Pred2.size() > 2) 363110267Sjeff return false; 364110267Sjeff 365110267Sjeff ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm(); 366110267Sjeff ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm(); 367113357Sjeff if (CC1 == CC2) 368112994Sjeff return true; 369113357Sjeff 370113357Sjeff switch (CC1) { 371113357Sjeff default: 372113357Sjeff return false; 373113357Sjeff case ARMCC::AL: 374113357Sjeff return true; 375113357Sjeff case ARMCC::HS: 376113357Sjeff return CC2 == ARMCC::HI; 377113357Sjeff case ARMCC::LS: 378113357Sjeff return CC2 == ARMCC::LO || CC2 == ARMCC::EQ; 379113357Sjeff case ARMCC::GE: 380113357Sjeff return CC2 == ARMCC::GT; 381113357Sjeff case ARMCC::LE: 382113357Sjeff return CC2 == ARMCC::LT; 383113357Sjeff } 384113357Sjeff} 385113357Sjeff 386113357Sjeffbool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, 387113357Sjeff std::vector<MachineOperand> &Pred) const { 388113357Sjeff // FIXME: This confuses implicit_def with optional CPSR def. 389113357Sjeff const TargetInstrDesc &TID = MI->getDesc(); 390113357Sjeff if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) 391113357Sjeff return false; 392113357Sjeff 393113357Sjeff bool Found = false; 394113357Sjeff for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 395110267Sjeff const MachineOperand &MO = MI->getOperand(i); 396110267Sjeff if (MO.isReg() && MO.getReg() == ARM::CPSR) { 397113357Sjeff Pred.push_back(MO); 398110267Sjeff Found = true; 399110267Sjeff } 400109864Sjeff } 401110028Sjeff 402110028Sjeff return Found; 403113357Sjeff} 404113357Sjeff 405112994Sjeff/// isPredicable - Return true if the specified instruction can be predicated. 406113357Sjeff/// By default, this returns true for every instruction with a 407113357Sjeff/// PredicateOperand. 408113357Sjeffbool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const { 409113357Sjeff const TargetInstrDesc &TID = MI->getDesc(); 410113357Sjeff if (!TID.isPredicable()) 411113357Sjeff return false; 412113357Sjeff 413113357Sjeff if ((TID.TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) { 414110267Sjeff ARMFunctionInfo *AFI = 415110267Sjeff MI->getParent()->getParent()->getInfo<ARMFunctionInfo>(); 416110267Sjeff return AFI->isThumb2Function(); 417110028Sjeff } 418110028Sjeff return true; 419110028Sjeff} 420109864Sjeff 421109864Sjeff/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing. 422109864SjeffDISABLE_INLINE 423109864Sjeffstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 424113357Sjeff unsigned JTI); 425113357Sjeffstatic unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 426111857Sjeff unsigned JTI) { 427109864Sjeff assert(JTI < JT.size()); 428109864Sjeff return JT[JTI].MBBs.size(); 429110028Sjeff} 430110028Sjeff 431113357Sjeff/// GetInstSize - Return the size of the specified MachineInstr. 432113357Sjeff/// 433109864Sjeffunsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 434109864Sjeff const MachineBasicBlock &MBB = *MI->getParent(); 435109864Sjeff const MachineFunction *MF = MBB.getParent(); 436109864Sjeff const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); 437109864Sjeff 438109864Sjeff // Basic size info comes from the TSFlags field. 439109864Sjeff const TargetInstrDesc &TID = MI->getDesc(); 440113357Sjeff unsigned TSFlags = TID.TSFlags; 441109864Sjeff 442109864Sjeff unsigned Opc = MI->getOpcode(); 443109864Sjeff switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) { 444109864Sjeff default: { 445109864Sjeff // If this machine instr is an inline asm, measure it. 446113357Sjeff if (MI->getOpcode() == ARM::INLINEASM) 447109864Sjeff return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI); 448113357Sjeff if (MI->isLabel()) 449111857Sjeff return 0; 450109864Sjeff switch (Opc) { 451109864Sjeff default: 452109864Sjeff llvm_unreachable("Unknown or unset size field for instr!"); 453109864Sjeff case TargetInstrInfo::IMPLICIT_DEF: 454109864Sjeff case TargetInstrInfo::KILL: 455109864Sjeff case TargetInstrInfo::DBG_LABEL: 456109864Sjeff case TargetInstrInfo::EH_LABEL: 457109864Sjeff return 0; 458109864Sjeff } 459113357Sjeff break; 460109864Sjeff } 461109864Sjeff case ARMII::Size8Bytes: return 8; // ARM instruction x 2. 462109864Sjeff case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction. 463112966Sjeff case ARMII::Size2Bytes: return 2; // Thumb1 instruction. 464112994Sjeff case ARMII::SizeSpecial: { 465109864Sjeff switch (Opc) { 466112966Sjeff case ARM::CONSTPOOL_ENTRY: 467112966Sjeff // If this machine instr is a constant pool entry, its size is recorded as 468109864Sjeff // operand #2. 469113357Sjeff return MI->getOperand(2).getImm(); 470112966Sjeff case ARM::Int_eh_sjlj_setjmp: 471109864Sjeff return 24; 472112966Sjeff case ARM::tInt_eh_sjlj_setjmp: 473113357Sjeff return 22; 474109864Sjeff case ARM::t2Int_eh_sjlj_setjmp: 475112966Sjeff return 22; 476112966Sjeff case ARM::BR_JTr: 477112966Sjeff case ARM::BR_JTm: 478112966Sjeff case ARM::BR_JTadd: 479112966Sjeff case ARM::tBR_JTr: 480112966Sjeff case ARM::t2BR_JT: 481112966Sjeff case ARM::t2TBB: 482112966Sjeff case ARM::t2TBH: { 483112966Sjeff // These are jumptable branches, i.e. a branch followed by an inlined 484112966Sjeff // jumptable. The size is 4 + 4 * number of entries. For TBB, each 485112966Sjeff // entry is one byte; TBH two byte each. 486112966Sjeff unsigned EntrySize = (Opc == ARM::t2TBB) 487112966Sjeff ? 1 : ((Opc == ARM::t2TBH) ? 2 : 4); 488112966Sjeff unsigned NumOps = TID.getNumOperands(); 489112966Sjeff MachineOperand JTOP = 490112966Sjeff MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2)); 491112966Sjeff unsigned JTI = JTOP.getIndex(); 492112966Sjeff const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 493112966Sjeff const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 494112966Sjeff assert(JTI < JT.size()); 495112966Sjeff // Thumb instructions are 2 byte aligned, but JT entries are 4 byte 496112966Sjeff // 4 aligned. The assembler / linker may add 2 byte padding just before 497109864Sjeff // the JT entries. The size does not include this padding; the 498113357Sjeff // constant islands pass does separate bookkeeping for it. 499112966Sjeff // FIXME: If we know the size of the function is less than (1 << 16) *2 500112966Sjeff // bytes, we can use 16-bit entries instead. Then there won't be an 501113357Sjeff // alignment issue. 502113357Sjeff unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4; 503113357Sjeff unsigned NumEntries = getNumJTEntries(JT, JTI); 504112966Sjeff if (Opc == ARM::t2TBB && (NumEntries & 1)) 505113357Sjeff // Make sure the instruction that follows TBB is 2-byte aligned. 506112966Sjeff // FIXME: Constant island pass should insert an "ALIGN" instruction 507112966Sjeff // instead. 508112966Sjeff ++NumEntries; 509112966Sjeff return NumEntries * EntrySize + InstSize; 510112966Sjeff } 511112966Sjeff default: 512113357Sjeff // Otherwise, pseudo-instruction sizes are zero. 513113357Sjeff return 0; 514113357Sjeff } 515113357Sjeff } 516113357Sjeff } 517110645Sjeff return 0; // Not reached 518112994Sjeff} 519112994Sjeff 520112994Sjeff/// Return true if the instruction is a register to register move and 521110645Sjeff/// leave the source and dest operands in the passed parameters. 522113357Sjeff/// 523113357Sjeffbool 524113357SjeffARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI, 525113357Sjeff unsigned &SrcReg, unsigned &DstReg, 526110645Sjeff unsigned& SrcSubIdx, unsigned& DstSubIdx) const { 527110645Sjeff SrcSubIdx = DstSubIdx = 0; // No sub-registers. 528110645Sjeff 529110645Sjeff switch (MI.getOpcode()) { 530113357Sjeff default: break; 531113357Sjeff case ARM::VMOVS: 532113357Sjeff case ARM::VMOVD: 533110645Sjeff case ARM::VMOVDneon: 534112966Sjeff case ARM::VMOVQ: { 535109864Sjeff SrcReg = MI.getOperand(1).getReg(); 536109864Sjeff DstReg = MI.getOperand(0).getReg(); 537111857Sjeff return true; 538111857Sjeff } 539111857Sjeff case ARM::MOVr: 540111857Sjeff case ARM::tMOVr: 541111857Sjeff case ARM::tMOVgpr2tgpr: 542111857Sjeff case ARM::tMOVtgpr2gpr: 543111857Sjeff case ARM::tMOVgpr2gpr: 544111857Sjeff case ARM::t2MOVr: { 545111857Sjeff assert(MI.getDesc().getNumOperands() >= 2 && 546111857Sjeff MI.getOperand(0).isReg() && 547111857Sjeff MI.getOperand(1).isReg() && 548111857Sjeff "Invalid ARM MOV instruction"); 549111857Sjeff SrcReg = MI.getOperand(1).getReg(); 550111857Sjeff DstReg = MI.getOperand(0).getReg(); 551111857Sjeff return true; 552111857Sjeff } 553111857Sjeff } 554111857Sjeff 555111857Sjeff return false; 556111857Sjeff} 557111857Sjeff 558111857Sjeffunsigned 559111857SjeffARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 560111857Sjeff int &FrameIndex) const { 561111857Sjeff switch (MI->getOpcode()) { 562111857Sjeff default: break; 563111857Sjeff case ARM::LDR: 564111857Sjeff case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame. 565113357Sjeff if (MI->getOperand(1).isFI() && 566113357Sjeff MI->getOperand(2).isReg() && 567113357Sjeff MI->getOperand(3).isImm() && 568113357Sjeff MI->getOperand(2).getReg() == 0 && 569113357Sjeff MI->getOperand(3).getImm() == 0) { 570109864Sjeff FrameIndex = MI->getOperand(1).getIndex(); 571109864Sjeff return MI->getOperand(0).getReg(); 572109864Sjeff } 573109864Sjeff break; 574109864Sjeff case ARM::t2LDRi12: 575109864Sjeff case ARM::tRestore: 576109864Sjeff if (MI->getOperand(1).isFI() && 577109864Sjeff MI->getOperand(2).isImm() && 578109864Sjeff MI->getOperand(2).getImm() == 0) { 579109864Sjeff FrameIndex = MI->getOperand(1).getIndex(); 580109864Sjeff return MI->getOperand(0).getReg(); 581113357Sjeff } 582111793Sjeff break; 583111793Sjeff case ARM::VLDRD: 584111793Sjeff case ARM::VLDRS: 585111793Sjeff if (MI->getOperand(1).isFI() && 586109864Sjeff MI->getOperand(2).isImm() && 587109864Sjeff MI->getOperand(2).getImm() == 0) { 588111793Sjeff FrameIndex = MI->getOperand(1).getIndex(); 589109864Sjeff return MI->getOperand(0).getReg(); 590109864Sjeff } 591109864Sjeff break; 592109864Sjeff } 593109864Sjeff 594110267Sjeff return 0; 595109864Sjeff} 596109864Sjeff 597109864Sjeffunsigned 598110028SjeffARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 599110028Sjeff int &FrameIndex) const { 600109864Sjeff switch (MI->getOpcode()) { 601109864Sjeff default: break; 602109864Sjeff case ARM::STR: 603109864Sjeff case ARM::t2STRs: // FIXME: don't use t2STRs to access frame. 604109864Sjeff if (MI->getOperand(1).isFI() && 605109864Sjeff MI->getOperand(2).isReg() && 606110028Sjeff MI->getOperand(3).isImm() && 607110028Sjeff MI->getOperand(2).getReg() == 0 && 608109864Sjeff MI->getOperand(3).getImm() == 0) { 609109864Sjeff FrameIndex = MI->getOperand(1).getIndex(); 610109864Sjeff return MI->getOperand(0).getReg(); 611109864Sjeff } 612110028Sjeff break; 613113357Sjeff case ARM::t2STRi12: 614109864Sjeff case ARM::tSpill: 615113357Sjeff if (MI->getOperand(1).isFI() && 616109864Sjeff MI->getOperand(2).isImm() && 617109864Sjeff MI->getOperand(2).getImm() == 0) { 618109864Sjeff FrameIndex = MI->getOperand(1).getIndex(); 619109864Sjeff return MI->getOperand(0).getReg(); 620109864Sjeff } 621109864Sjeff break; 622109864Sjeff case ARM::VSTRD: 623109864Sjeff case ARM::VSTRS: 624109864Sjeff if (MI->getOperand(1).isFI() && 625109864Sjeff MI->getOperand(2).isImm() && 626109864Sjeff MI->getOperand(2).getImm() == 0) { 627109864Sjeff FrameIndex = MI->getOperand(1).getIndex(); 628109864Sjeff return MI->getOperand(0).getReg(); 629109864Sjeff } 630109864Sjeff break; 631109864Sjeff } 632109864Sjeff 633109864Sjeff return 0; 634109864Sjeff} 635109864Sjeff 636109864Sjeffbool 637109864SjeffARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 638109864Sjeff MachineBasicBlock::iterator I, 639109864Sjeff unsigned DestReg, unsigned SrcReg, 640109864Sjeff const TargetRegisterClass *DestRC, 641109864Sjeff const TargetRegisterClass *SrcRC) const { 642109864Sjeff DebugLoc DL = DebugLoc::getUnknownLoc(); 643109864Sjeff if (I != MBB.end()) DL = I->getDebugLoc(); 644109864Sjeff 645109864Sjeff if (DestRC != SrcRC) { 646109864Sjeff if (DestRC->getSize() != SrcRC->getSize()) 647109864Sjeff return false; 648109864Sjeff 649109864Sjeff // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies. 650109864Sjeff // Allow QPR / QPR_VFP2 / QPR_8 cross-class copies. 651109864Sjeff if (DestRC->getSize() != 8 && DestRC->getSize() != 16) 652109864Sjeff return false; 653109864Sjeff } 654109864Sjeff 655109864Sjeff if (DestRC == ARM::GPRRegisterClass) { 656109864Sjeff AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), 657109864Sjeff DestReg).addReg(SrcReg))); 658113339Sjulian } else if (DestRC == ARM::SPRRegisterClass) { 659113339Sjulian AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVS), DestReg) 660111032Sjulian .addReg(SrcReg)); 661109864Sjeff } else if (DestRC == ARM::DPRRegisterClass) { 662109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg) 663113357Sjeff .addReg(SrcReg)); 664113357Sjeff } else if (DestRC == ARM::DPR_VFP2RegisterClass || 665109864Sjeff DestRC == ARM::DPR_8RegisterClass || 666111857Sjeff SrcRC == ARM::DPR_VFP2RegisterClass || 667113357Sjeff SrcRC == ARM::DPR_8RegisterClass) { 668113357Sjeff // Always use neon reg-reg move if source or dest is NEON-only regclass. 669109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVDneon), 670109864Sjeff DestReg).addReg(SrcReg)); 671109864Sjeff } else if (DestRC == ARM::QPRRegisterClass || 672109864Sjeff DestRC == ARM::QPR_VFP2RegisterClass || 673111585Sjulian DestRC == ARM::QPR_8RegisterClass) { 674109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVQ), 675109864Sjeff DestReg).addReg(SrcReg)); 676109864Sjeff } else { 677109864Sjeff return false; 678109864Sjeff } 679109864Sjeff 680109864Sjeff return true; 681109864Sjeff} 682109864Sjeff 683113339Sjulianvoid ARMBaseInstrInfo:: 684113357SjeffstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 685109864Sjeff unsigned SrcReg, bool isKill, int FI, 686109864Sjeff const TargetRegisterClass *RC) const { 687111032Sjulian DebugLoc DL = DebugLoc::getUnknownLoc(); 688109864Sjeff if (I != MBB.end()) DL = I->getDebugLoc(); 689109864Sjeff MachineFunction &MF = *MBB.getParent(); 690109864Sjeff MachineFrameInfo &MFI = *MF.getFrameInfo(); 691109864Sjeff unsigned Align = MFI.getObjectAlignment(FI); 692109864Sjeff 693113357Sjeff MachineMemOperand *MMO = 694109864Sjeff MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI), 695113357Sjeff MachineMemOperand::MOStore, 0, 696109864Sjeff MFI.getObjectSize(FI), 697113357Sjeff Align); 698113357Sjeff 699113357Sjeff if (RC == ARM::GPRRegisterClass) { 700113357Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) 701113357Sjeff .addReg(SrcReg, getKillRegState(isKill)) 702113357Sjeff .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO)); 703113357Sjeff } else if (RC == ARM::DPRRegisterClass || 704113357Sjeff RC == ARM::DPR_VFP2RegisterClass || 705113357Sjeff RC == ARM::DPR_8RegisterClass) { 706113357Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD)) 707113357Sjeff .addReg(SrcReg, getKillRegState(isKill)) 708113357Sjeff .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 709109864Sjeff } else if (RC == ARM::SPRRegisterClass) { 710109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS)) 711113357Sjeff .addReg(SrcReg, getKillRegState(isKill)) 712111032Sjulian .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 713109864Sjeff } else { 714109864Sjeff assert((RC == ARM::QPRRegisterClass || 715109864Sjeff RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!"); 716109864Sjeff // FIXME: Neon instructions should support predicates 717109864Sjeff if (Align >= 16 718109864Sjeff && (getRegisterInfo().needsStackRealignment(MF))) { 719109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64)) 720109864Sjeff .addFrameIndex(FI).addImm(0).addImm(0).addImm(128) 721109864Sjeff .addMemOperand(MMO) 722109864Sjeff .addReg(SrcReg, getKillRegState(isKill))); 723113357Sjeff } else { 724113357Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRQ)). 725109864Sjeff addReg(SrcReg, getKillRegState(isKill)) 726109864Sjeff .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 727109864Sjeff } 728109864Sjeff } 729109864Sjeff} 730109864Sjeff 731109864Sjeffvoid ARMBaseInstrInfo:: 732109864SjeffloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 733109864Sjeff unsigned DestReg, int FI, 734109864Sjeff const TargetRegisterClass *RC) const { 735109864Sjeff DebugLoc DL = DebugLoc::getUnknownLoc(); 736111788Sjeff if (I != MBB.end()) DL = I->getDebugLoc(); 737111788Sjeff MachineFunction &MF = *MBB.getParent(); 738113357Sjeff MachineFrameInfo &MFI = *MF.getFrameInfo(); 739109864Sjeff unsigned Align = MFI.getObjectAlignment(FI); 740111788Sjeff 741113357Sjeff MachineMemOperand *MMO = 742113357Sjeff MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI), 743111788Sjeff MachineMemOperand::MOLoad, 0, 744113357Sjeff MFI.getObjectSize(FI), 745113357Sjeff Align); 746111788Sjeff 747109864Sjeff if (RC == ARM::GPRRegisterClass) { 748109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) 749109864Sjeff .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO)); 750111032Sjulian } else if (RC == ARM::DPRRegisterClass || 751109864Sjeff RC == ARM::DPR_VFP2RegisterClass || 752109864Sjeff RC == ARM::DPR_8RegisterClass) { 753109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg) 754109864Sjeff .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 755109864Sjeff } else if (RC == ARM::SPRRegisterClass) { 756109864Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg) 757109864Sjeff .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 758113357Sjeff } else { 759109864Sjeff assert((RC == ARM::QPRRegisterClass || 760109864Sjeff RC == ARM::QPR_VFP2RegisterClass || 761109864Sjeff RC == ARM::QPR_8RegisterClass) && "Unknown regclass!"); 762109864Sjeff if (Align >= 16 763113357Sjeff && (getRegisterInfo().needsStackRealignment(MF))) { 764113357Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg) 765113357Sjeff .addFrameIndex(FI).addImm(0).addImm(0).addImm(128) 766113357Sjeff .addMemOperand(MMO)); 767113357Sjeff } else { 768113357Sjeff AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg) 769113357Sjeff .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 770113357Sjeff } 771113357Sjeff } 772113357Sjeff} 773113357Sjeff 774113357SjeffMachineInstr *ARMBaseInstrInfo:: 775113357SjefffoldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 776113357Sjeff const SmallVectorImpl<unsigned> &Ops, int FI) const { 777113357Sjeff if (Ops.size() != 1) return NULL; 778113357Sjeff 779113357Sjeff unsigned OpNum = Ops[0]; 780113357Sjeff unsigned Opc = MI->getOpcode(); 781113357Sjeff MachineInstr *NewMI = NULL; 782113357Sjeff if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 783113357Sjeff // If it is updating CPSR, then it cannot be folded. 784113357Sjeff if (MI->getOperand(4).getReg() == ARM::CPSR && !MI->getOperand(4).isDead()) 785113357Sjeff return NULL; 786113357Sjeff unsigned Pred = MI->getOperand(2).getImm(); 787109864Sjeff unsigned PredReg = MI->getOperand(3).getReg(); 788110645Sjeff if (OpNum == 0) { // move -> store 789111857Sjeff unsigned SrcReg = MI->getOperand(1).getReg(); 790111857Sjeff unsigned SrcSubReg = MI->getOperand(1).getSubReg(); 791110645Sjeff bool isKill = MI->getOperand(1).isKill(); 792111857Sjeff bool isUndef = MI->getOperand(1).isUndef(); 793111857Sjeff if (Opc == ARM::MOVr) 794110645Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) 795113357Sjeff .addReg(SrcReg, 796109864Sjeff getKillRegState(isKill) | getUndefRegState(isUndef), 797113357Sjeff SrcSubReg) 798113357Sjeff .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 799109864Sjeff else // ARM::t2MOVr 800113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12)) 801113357Sjeff .addReg(SrcReg, 802113357Sjeff getKillRegState(isKill) | getUndefRegState(isUndef), 803113357Sjeff SrcSubReg) 804113357Sjeff .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 805113357Sjeff } else { // move -> load 806113357Sjeff unsigned DstReg = MI->getOperand(0).getReg(); 807113357Sjeff unsigned DstSubReg = MI->getOperand(0).getSubReg(); 808113357Sjeff bool isDead = MI->getOperand(0).isDead(); 809113357Sjeff bool isUndef = MI->getOperand(0).isUndef(); 810113357Sjeff if (Opc == ARM::MOVr) 811113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) 812113357Sjeff .addReg(DstReg, 813113357Sjeff RegState::Define | 814113357Sjeff getDeadRegState(isDead) | 815113357Sjeff getUndefRegState(isUndef), DstSubReg) 816113357Sjeff .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 817113357Sjeff else // ARM::t2MOVr 818113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12)) 819113357Sjeff .addReg(DstReg, 820113357Sjeff RegState::Define | 821113357Sjeff getDeadRegState(isDead) | 822113357Sjeff getUndefRegState(isUndef), DstSubReg) 823113357Sjeff .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 824113357Sjeff } 825113357Sjeff } else if (Opc == ARM::tMOVgpr2gpr || 826113357Sjeff Opc == ARM::tMOVtgpr2gpr || 827109970Sjeff Opc == ARM::tMOVgpr2tgpr) { 828109970Sjeff if (OpNum == 0) { // move -> store 829113357Sjeff unsigned SrcReg = MI->getOperand(1).getReg(); 830109864Sjeff unsigned SrcSubReg = MI->getOperand(1).getSubReg(); 831109864Sjeff bool isKill = MI->getOperand(1).isKill(); 832109864Sjeff bool isUndef = MI->getOperand(1).isUndef(); 833109864Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12)) 834109864Sjeff .addReg(SrcReg, 835109864Sjeff getKillRegState(isKill) | getUndefRegState(isUndef), 836113357Sjeff SrcSubReg) 837109864Sjeff .addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0); 838113357Sjeff } else { // move -> load 839113357Sjeff unsigned DstReg = MI->getOperand(0).getReg(); 840113357Sjeff unsigned DstSubReg = MI->getOperand(0).getSubReg(); 841109864Sjeff bool isDead = MI->getOperand(0).isDead(); 842109864Sjeff bool isUndef = MI->getOperand(0).isUndef(); 843113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12)) 844113357Sjeff .addReg(DstReg, 845113357Sjeff RegState::Define | 846109864Sjeff getDeadRegState(isDead) | 847109864Sjeff getUndefRegState(isUndef), 848109864Sjeff DstSubReg) 849113357Sjeff .addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0); 850109864Sjeff } 851113357Sjeff } else if (Opc == ARM::VMOVS) { 852113357Sjeff unsigned Pred = MI->getOperand(2).getImm(); 853113357Sjeff unsigned PredReg = MI->getOperand(3).getReg(); 854113357Sjeff if (OpNum == 0) { // move -> store 855109864Sjeff unsigned SrcReg = MI->getOperand(1).getReg(); 856110267Sjeff unsigned SrcSubReg = MI->getOperand(1).getSubReg(); 857109864Sjeff bool isKill = MI->getOperand(1).isKill(); 858113357Sjeff bool isUndef = MI->getOperand(1).isUndef(); 859113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRS)) 860113357Sjeff .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef), 861113357Sjeff SrcSubReg) 862113357Sjeff .addFrameIndex(FI) 863113357Sjeff .addImm(0).addImm(Pred).addReg(PredReg); 864113357Sjeff } else { // move -> load 865113357Sjeff unsigned DstReg = MI->getOperand(0).getReg(); 866113357Sjeff unsigned DstSubReg = MI->getOperand(0).getSubReg(); 867113357Sjeff bool isDead = MI->getOperand(0).isDead(); 868113357Sjeff bool isUndef = MI->getOperand(0).isUndef(); 869113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRS)) 870113357Sjeff .addReg(DstReg, 871113357Sjeff RegState::Define | 872113357Sjeff getDeadRegState(isDead) | 873109864Sjeff getUndefRegState(isUndef), 874113357Sjeff DstSubReg) 875113357Sjeff .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 876109864Sjeff } 877110028Sjeff } 878110028Sjeff else if (Opc == ARM::VMOVD) { 879110028Sjeff unsigned Pred = MI->getOperand(2).getImm(); 880110028Sjeff unsigned PredReg = MI->getOperand(3).getReg(); 881111793Sjeff if (OpNum == 0) { // move -> store 882109971Sjeff unsigned SrcReg = MI->getOperand(1).getReg(); 883112994Sjeff unsigned SrcSubReg = MI->getOperand(1).getSubReg(); 884109971Sjeff bool isKill = MI->getOperand(1).isKill(); 885109971Sjeff bool isUndef = MI->getOperand(1).isUndef(); 886109971Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRD)) 887109971Sjeff .addReg(SrcReg, 888110028Sjeff getKillRegState(isKill) | getUndefRegState(isUndef), 889109864Sjeff SrcSubReg) 890110028Sjeff .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 891113357Sjeff } else { // move -> load 892113357Sjeff unsigned DstReg = MI->getOperand(0).getReg(); 893113357Sjeff unsigned DstSubReg = MI->getOperand(0).getSubReg(); 894110028Sjeff bool isDead = MI->getOperand(0).isDead(); 895113357Sjeff bool isUndef = MI->getOperand(0).isUndef(); 896113357Sjeff NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRD)) 897113357Sjeff .addReg(DstReg, 898113357Sjeff RegState::Define | 899113357Sjeff getDeadRegState(isDead) | 900110028Sjeff getUndefRegState(isUndef), 901110028Sjeff DstSubReg) 902110028Sjeff .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 903110028Sjeff } 904113357Sjeff } 905113357Sjeff 906113357Sjeff return NewMI; 907113357Sjeff} 908113357Sjeff 909113357SjeffMachineInstr* 910113357SjeffARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 911113357Sjeff MachineInstr* MI, 912113357Sjeff const SmallVectorImpl<unsigned> &Ops, 913113357Sjeff MachineInstr* LoadMI) const { 914113357Sjeff // FIXME 915110267Sjeff return 0; 916109864Sjeff} 917110645Sjeff 918113357Sjeffbool 919109864SjeffARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, 920113357Sjeff const SmallVectorImpl<unsigned> &Ops) const { 921110645Sjeff if (Ops.size() != 1) return false; 922109864Sjeff 923109864Sjeff unsigned Opc = MI->getOpcode(); 924109864Sjeff if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 925109864Sjeff // If it is updating CPSR, then it cannot be folded. 926113357Sjeff return MI->getOperand(4).getReg() != ARM::CPSR || 927113370Sjeff MI->getOperand(4).isDead(); 928113357Sjeff } else if (Opc == ARM::tMOVgpr2gpr || 929113357Sjeff Opc == ARM::tMOVtgpr2gpr || 930113357Sjeff Opc == ARM::tMOVgpr2tgpr) { 931113357Sjeff return true; 932109864Sjeff } else if (Opc == ARM::VMOVS || Opc == ARM::VMOVD) { 933113357Sjeff return true; 934109864Sjeff } else if (Opc == ARM::VMOVDneon || Opc == ARM::VMOVQ) { 935113357Sjeff return false; // FIXME 936113357Sjeff } 937113357Sjeff 938113357Sjeff return false; 939113357Sjeff} 940113357Sjeff 941113357Sjeffvoid ARMBaseInstrInfo:: 942113357SjeffreMaterialize(MachineBasicBlock &MBB, 943113357Sjeff MachineBasicBlock::iterator I, 944109864Sjeff unsigned DestReg, unsigned SubIdx, 945109864Sjeff const MachineInstr *Orig, 946109864Sjeff const TargetRegisterInfo *TRI) const { 947109864Sjeff if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) { 948109864Sjeff DestReg = TRI->getSubReg(DestReg, SubIdx); 949109864Sjeff SubIdx = 0; 950109864Sjeff } 951110028Sjeff 952109864Sjeff unsigned Opcode = Orig->getOpcode(); 953113357Sjeff switch (Opcode) { 954109970Sjeff default: { 955109970Sjeff MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); 956110028Sjeff MI->getOperand(0).setReg(DestReg); 957110028Sjeff MBB.insert(I, MI); 958110028Sjeff break; 959110028Sjeff } 960109970Sjeff case ARM::tLDRpci_pic: 961109970Sjeff case ARM::t2LDRpci_pic: { 962109970Sjeff MachineFunction &MF = *MBB.getParent(); 963109970Sjeff ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 964109970Sjeff MachineConstantPool *MCP = MF.getConstantPool(); 965109970Sjeff unsigned CPI = Orig->getOperand(1).getIndex(); 966110028Sjeff const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI]; 967113357Sjeff assert(MCPE.isMachineConstantPoolEntry() && 968109970Sjeff "Expecting a machine constantpool entry!"); 969109970Sjeff ARMConstantPoolValue *ACPV = 970109970Sjeff static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal); 971109970Sjeff unsigned PCLabelId = AFI->createConstPoolEntryUId(); 972109970Sjeff ARMConstantPoolValue *NewCPV = 0; 973109864Sjeff if (ACPV->isGlobalValue()) 974109864Sjeff NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId, 975109864Sjeff ARMCP::CPValue, 4); 976109864Sjeff else if (ACPV->isExtSymbol()) 977109864Sjeff NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(), 978109864Sjeff ACPV->getSymbol(), PCLabelId, 4); 979109864Sjeff else if (ACPV->isBlockAddress()) 980109864Sjeff NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId, 981109864Sjeff ARMCP::CPBlockAddress, 4); 982109864Sjeff else 983109864Sjeff llvm_unreachable("Unexpected ARM constantpool value type!!"); 984109864Sjeff CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment()); 985109864Sjeff MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode), 986109864Sjeff DestReg) 987109864Sjeff .addConstantPoolIndex(CPI).addImm(PCLabelId); 988109864Sjeff (*MIB).setMemRefs(Orig->memoperands_begin(), Orig->memoperands_end()); 989109864Sjeff break; 990109970Sjeff } 991109970Sjeff } 992110028Sjeff 993109970Sjeff MachineInstr *NewMI = prior(I); 994109970Sjeff NewMI->getOperand(0).setSubReg(SubIdx); 995113357Sjeff} 996112966Sjeff 997113357Sjeffbool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0, 998113370Sjeff const MachineInstr *MI1, 999110028Sjeff const MachineRegisterInfo *MRI) const { 1000109864Sjeff int Opcode = MI0->getOpcode(); 1001113357Sjeff if (Opcode == ARM::t2LDRpci || 1002109864Sjeff Opcode == ARM::t2LDRpci_pic || 1003112966Sjeff Opcode == ARM::tLDRpci || 1004113357Sjeff Opcode == ARM::tLDRpci_pic) { 1005113357Sjeff if (MI1->getOpcode() != Opcode) 1006113357Sjeff return false; 1007113357Sjeff if (MI0->getNumOperands() != MI1->getNumOperands()) 1008113357Sjeff return false; 1009113357Sjeff 1010109864Sjeff const MachineOperand &MO0 = MI0->getOperand(1); 1011109864Sjeff const MachineOperand &MO1 = MI1->getOperand(1); 1012109970Sjeff if (MO0.getOffset() != MO1.getOffset()) 1013113370Sjeff return false; 1014109970Sjeff 1015109970Sjeff const MachineFunction *MF = MI0->getParent()->getParent(); 1016109970Sjeff const MachineConstantPool *MCP = MF->getConstantPool(); 1017113370Sjeff int CPI0 = MO0.getIndex(); 1018113370Sjeff int CPI1 = MO1.getIndex(); 1019113370Sjeff const MachineConstantPoolEntry &MCPE0 = MCP->getConstants()[CPI0]; 1020113370Sjeff const MachineConstantPoolEntry &MCPE1 = MCP->getConstants()[CPI1]; 1021113370Sjeff ARMConstantPoolValue *ACPV0 = 1022113370Sjeff static_cast<ARMConstantPoolValue*>(MCPE0.Val.MachineCPVal); 1023113370Sjeff ARMConstantPoolValue *ACPV1 = 1024113370Sjeff static_cast<ARMConstantPoolValue*>(MCPE1.Val.MachineCPVal); 1025113370Sjeff return ACPV0->hasSameValue(ACPV1); 1026113370Sjeff } 1027113370Sjeff 1028113370Sjeff return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI); 1029113370Sjeff} 1030113370Sjeff 1031113370Sjeff/// getInstrPredicate - If instruction is predicated, returns its predicate 1032113370Sjeff/// condition, otherwise returns AL. It also returns the condition code 1033109970Sjeff/// register by reference. 1034109970SjeffARMCC::CondCodes 1035113357Sjeffllvm::getInstrPredicate(const MachineInstr *MI, unsigned &PredReg) { 1036113357Sjeff int PIdx = MI->findFirstPredOperandIdx(); 1037109864Sjeff if (PIdx == -1) { 1038109864Sjeff PredReg = 0; 1039109864Sjeff return ARMCC::AL; 1040109864Sjeff } 1041109864Sjeff 1042110267Sjeff PredReg = MI->getOperand(PIdx+1).getReg(); 1043113357Sjeff return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm(); 1044109864Sjeff} 1045109864Sjeff 1046110267Sjeff 1047109864Sjeffint llvm::getMatchingCondBranchOpcode(int Opc) { 1048110267Sjeff if (Opc == ARM::B) 1049109864Sjeff return ARM::Bcc; 1050110267Sjeff else if (Opc == ARM::tB) 1051109864Sjeff return ARM::tBcc; 1052109864Sjeff else if (Opc == ARM::t2B) 1053110267Sjeff return ARM::t2Bcc; 1054109864Sjeff 1055113357Sjeff llvm_unreachable("Unknown unconditional branch opcode!"); 1056113357Sjeff return 0; 1057113357Sjeff} 1058113357Sjeff 1059113357Sjeff 1060113357Sjeffvoid llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB, 1061112994Sjeff MachineBasicBlock::iterator &MBBI, DebugLoc dl, 1062112994Sjeff unsigned DestReg, unsigned BaseReg, int NumBytes, 1063112994Sjeff ARMCC::CondCodes Pred, unsigned PredReg, 1064113357Sjeff const ARMBaseInstrInfo &TII) { 1065113357Sjeff bool isSub = NumBytes < 0; 1066113357Sjeff if (isSub) NumBytes = -NumBytes; 1067113357Sjeff 1068112994Sjeff while (NumBytes) { 1069112994Sjeff unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 1070113357Sjeff unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 1071113357Sjeff assert(ThisVal && "Didn't extract field correctly"); 1072113357Sjeff 1073113357Sjeff // We will handle these bits from offset, clear them. 1074113357Sjeff NumBytes &= ~ThisVal; 1075113357Sjeff 1076113357Sjeff assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?"); 1077113357Sjeff 1078113357Sjeff // Build the new ADD / SUB. 1079112994Sjeff unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri; 1080111789Sjeff BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 1081113357Sjeff .addReg(BaseReg, RegState::Kill).addImm(ThisVal) 1082113357Sjeff .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 1083113357Sjeff BaseReg = DestReg; 1084113357Sjeff } 1085113357Sjeff} 1086113357Sjeff 1087113357Sjeffbool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 1088113357Sjeff unsigned FrameReg, int &Offset, 1089113357Sjeff const ARMBaseInstrInfo &TII) { 1090113357Sjeff unsigned Opcode = MI.getOpcode(); 1091113357Sjeff const TargetInstrDesc &Desc = MI.getDesc(); 1092112994Sjeff unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 1093113357Sjeff bool isSub = false; 1094113357Sjeff 1095113357Sjeff // Memory operands in inline assembly always use AddrMode2. 1096112994Sjeff if (Opcode == ARM::INLINEASM) 1097109864Sjeff AddrMode = ARMII::AddrMode2; 1098109864Sjeff 1099109864Sjeff if (Opcode == ARM::ADDri) { 1100109864Sjeff Offset += MI.getOperand(FrameRegIdx+1).getImm(); 1101113357Sjeff if (Offset == 0) { 1102109864Sjeff // Turn it into a move. 1103109864Sjeff MI.setDesc(TII.get(ARM::MOVr)); 1104109864Sjeff MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 1105109864Sjeff MI.RemoveOperand(FrameRegIdx+1); 1106109864Sjeff Offset = 0; 1107113357Sjeff return true; 1108113357Sjeff } else if (Offset < 0) { 1109109864Sjeff Offset = -Offset; 1110109864Sjeff isSub = true; 1111113357Sjeff MI.setDesc(TII.get(ARM::SUBri)); 1112109864Sjeff } 1113109864Sjeff 1114109864Sjeff // Common case: small offset, fits into instruction. 1115113357Sjeff if (ARM_AM::getSOImmVal(Offset) != -1) { 1116113357Sjeff // Replace the FrameIndex with sp / fp 1117113357Sjeff MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 1118109864Sjeff MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 1119109864Sjeff Offset = 0; 1120109864Sjeff return true; 1121109864Sjeff } 1122109864Sjeff 1123109864Sjeff // Otherwise, pull as much of the immedidate into this ADDri/SUBri 1124109864Sjeff // as possible. 1125109864Sjeff unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 1126109864Sjeff unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); 1127109864Sjeff 1128109864Sjeff // We will handle these bits from offset, clear them. 1129109864Sjeff Offset &= ~ThisImmVal; 1130109864Sjeff 1131109864Sjeff // Get the properly encoded SOImmVal field. 1132109864Sjeff assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 && 1133109864Sjeff "Bit extraction didn't work?"); 1134109864Sjeff MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); 1135111793Sjeff } else { 1136110226Sscottl unsigned ImmIdx = 0; 1137109864Sjeff int InstrOffs = 0; 1138109864Sjeff unsigned NumBits = 0; 1139109864Sjeff unsigned Scale = 1; 1140109864Sjeff switch (AddrMode) { 1141109864Sjeff case ARMII::AddrMode2: { 1142109864Sjeff ImmIdx = FrameRegIdx+2; 1143109864Sjeff InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm()); 1144109864Sjeff if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 1145109864Sjeff InstrOffs *= -1; 1146109864Sjeff NumBits = 12; 1147109864Sjeff break; 1148109864Sjeff } 1149109864Sjeff case ARMII::AddrMode3: { 1150109864Sjeff ImmIdx = FrameRegIdx+2; 1151109864Sjeff InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm()); 1152109864Sjeff if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 1153109864Sjeff InstrOffs *= -1; 1154109864Sjeff NumBits = 8; 1155109864Sjeff break; 1156109864Sjeff } 1157109864Sjeff case ARMII::AddrMode4: 1158109864Sjeff case ARMII::AddrMode6: 1159109864Sjeff // Can't fold any offset even if it's zero. 1160109864Sjeff return false; 1161109864Sjeff case ARMII::AddrMode5: { 1162109864Sjeff ImmIdx = FrameRegIdx+1; 1163109864Sjeff InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 1164109864Sjeff if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 1165109864Sjeff InstrOffs *= -1; 1166109864Sjeff NumBits = 8; 1167 Scale = 4; 1168 break; 1169 } 1170 default: 1171 llvm_unreachable("Unsupported addressing mode!"); 1172 break; 1173 } 1174 1175 Offset += InstrOffs * Scale; 1176 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 1177 if (Offset < 0) { 1178 Offset = -Offset; 1179 isSub = true; 1180 } 1181 1182 // Attempt to fold address comp. if opcode has offset bits 1183 if (NumBits > 0) { 1184 // Common case: small offset, fits into instruction. 1185 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 1186 int ImmedOffset = Offset / Scale; 1187 unsigned Mask = (1 << NumBits) - 1; 1188 if ((unsigned)Offset <= Mask * Scale) { 1189 // Replace the FrameIndex with sp 1190 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 1191 if (isSub) 1192 ImmedOffset |= 1 << NumBits; 1193 ImmOp.ChangeToImmediate(ImmedOffset); 1194 Offset = 0; 1195 return true; 1196 } 1197 1198 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 1199 ImmedOffset = ImmedOffset & Mask; 1200 if (isSub) 1201 ImmedOffset |= 1 << NumBits; 1202 ImmOp.ChangeToImmediate(ImmedOffset); 1203 Offset &= ~(Mask*Scale); 1204 } 1205 } 1206 1207 Offset = (isSub) ? -Offset : Offset; 1208 return Offset == 0; 1209} 1210