1235633Sdim//===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file contains the XCore implementation of the TargetInstrInfo class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14235633Sdim#include "XCoreInstrInfo.h" 15252723Sdim#include "XCore.h" 16193323Sed#include "XCoreMachineFunctionInfo.h" 17252723Sdim#include "llvm/ADT/STLExtras.h" 18252723Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 19252723Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 20206274Srdivacky#include "llvm/MC/MCContext.h" 21193323Sed#include "llvm/Support/Debug.h" 22198090Srdivacky#include "llvm/Support/ErrorHandling.h" 23226890Sdim#include "llvm/Support/TargetRegistry.h" 24193323Sed 25263509Sdim#define GET_INSTRINFO_CTOR_DTOR 26224145Sdim#include "XCoreGenInstrInfo.inc" 27224145Sdim 28193323Sednamespace llvm { 29193323Sednamespace XCore { 30193323Sed 31193323Sed // XCore Condition Codes 32193323Sed enum CondCode { 33193323Sed COND_TRUE, 34193323Sed COND_FALSE, 35193323Sed COND_INVALID 36193323Sed }; 37193323Sed} 38193323Sed} 39193323Sed 40193323Sedusing namespace llvm; 41193323Sed 42263509Sdim 43263509Sdim// Pin the vtable to this file. 44263509Sdimvoid XCoreInstrInfo::anchor() {} 45263509Sdim 46198090SrdivackyXCoreInstrInfo::XCoreInstrInfo() 47224145Sdim : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 48263509Sdim RI() { 49193323Sed} 50193323Sed 51193323Sedstatic bool isZeroImm(const MachineOperand &op) { 52193323Sed return op.isImm() && op.getImm() == 0; 53193323Sed} 54193323Sed 55193323Sed/// isLoadFromStackSlot - If the specified machine instruction is a direct 56193323Sed/// load from a stack slot, return the virtual or physical register number of 57193323Sed/// the destination along with the FrameIndex of the loaded stack slot. If 58193323Sed/// not, return 0. This predicate must return 0 if the instruction has 59193323Sed/// any side effects other than loading from the stack slot. 60193323Sedunsigned 61193323SedXCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{ 62193323Sed int Opcode = MI->getOpcode(); 63193323Sed if (Opcode == XCore::LDWFI) 64193323Sed { 65193323Sed if ((MI->getOperand(1).isFI()) && // is a stack slot 66193323Sed (MI->getOperand(2).isImm()) && // the imm is zero 67193323Sed (isZeroImm(MI->getOperand(2)))) 68193323Sed { 69193323Sed FrameIndex = MI->getOperand(1).getIndex(); 70193323Sed return MI->getOperand(0).getReg(); 71193323Sed } 72193323Sed } 73193323Sed return 0; 74193323Sed} 75193323Sed 76193323Sed /// isStoreToStackSlot - If the specified machine instruction is a direct 77193323Sed /// store to a stack slot, return the virtual or physical register number of 78193323Sed /// the source reg along with the FrameIndex of the loaded stack slot. If 79193323Sed /// not, return 0. This predicate must return 0 if the instruction has 80193323Sed /// any side effects other than storing to the stack slot. 81193323Sedunsigned 82193323SedXCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 83193323Sed int &FrameIndex) const { 84193323Sed int Opcode = MI->getOpcode(); 85193323Sed if (Opcode == XCore::STWFI) 86193323Sed { 87193323Sed if ((MI->getOperand(1).isFI()) && // is a stack slot 88193323Sed (MI->getOperand(2).isImm()) && // the imm is zero 89193323Sed (isZeroImm(MI->getOperand(2)))) 90193323Sed { 91193323Sed FrameIndex = MI->getOperand(1).getIndex(); 92193323Sed return MI->getOperand(0).getReg(); 93193323Sed } 94193323Sed } 95193323Sed return 0; 96193323Sed} 97193323Sed 98193323Sed//===----------------------------------------------------------------------===// 99193323Sed// Branch Analysis 100193323Sed//===----------------------------------------------------------------------===// 101193323Sed 102193323Sedstatic inline bool IsBRU(unsigned BrOpc) { 103193323Sed return BrOpc == XCore::BRFU_u6 104193323Sed || BrOpc == XCore::BRFU_lu6 105193323Sed || BrOpc == XCore::BRBU_u6 106193323Sed || BrOpc == XCore::BRBU_lu6; 107193323Sed} 108193323Sed 109193323Sedstatic inline bool IsBRT(unsigned BrOpc) { 110193323Sed return BrOpc == XCore::BRFT_ru6 111193323Sed || BrOpc == XCore::BRFT_lru6 112193323Sed || BrOpc == XCore::BRBT_ru6 113193323Sed || BrOpc == XCore::BRBT_lru6; 114193323Sed} 115193323Sed 116193323Sedstatic inline bool IsBRF(unsigned BrOpc) { 117193323Sed return BrOpc == XCore::BRFF_ru6 118193323Sed || BrOpc == XCore::BRFF_lru6 119193323Sed || BrOpc == XCore::BRBF_ru6 120193323Sed || BrOpc == XCore::BRBF_lru6; 121193323Sed} 122193323Sed 123193323Sedstatic inline bool IsCondBranch(unsigned BrOpc) { 124193323Sed return IsBRF(BrOpc) || IsBRT(BrOpc); 125193323Sed} 126193323Sed 127204642Srdivackystatic inline bool IsBR_JT(unsigned BrOpc) { 128204642Srdivacky return BrOpc == XCore::BR_JT 129204642Srdivacky || BrOpc == XCore::BR_JT32; 130204642Srdivacky} 131204642Srdivacky 132193323Sed/// GetCondFromBranchOpc - Return the XCore CC that matches 133193323Sed/// the correspondent Branch instruction opcode. 134193323Sedstatic XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) 135193323Sed{ 136193323Sed if (IsBRT(BrOpc)) { 137193323Sed return XCore::COND_TRUE; 138193323Sed } else if (IsBRF(BrOpc)) { 139193323Sed return XCore::COND_FALSE; 140193323Sed } else { 141193323Sed return XCore::COND_INVALID; 142193323Sed } 143193323Sed} 144193323Sed 145193323Sed/// GetCondBranchFromCond - Return the Branch instruction 146193323Sed/// opcode that matches the cc. 147193323Sedstatic inline unsigned GetCondBranchFromCond(XCore::CondCode CC) 148193323Sed{ 149193323Sed switch (CC) { 150198090Srdivacky default: llvm_unreachable("Illegal condition code!"); 151193323Sed case XCore::COND_TRUE : return XCore::BRFT_lru6; 152193323Sed case XCore::COND_FALSE : return XCore::BRFF_lru6; 153193323Sed } 154193323Sed} 155193323Sed 156193323Sed/// GetOppositeBranchCondition - Return the inverse of the specified 157193323Sed/// condition, e.g. turning COND_E to COND_NE. 158193323Sedstatic inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) 159193323Sed{ 160193323Sed switch (CC) { 161198090Srdivacky default: llvm_unreachable("Illegal condition code!"); 162193323Sed case XCore::COND_TRUE : return XCore::COND_FALSE; 163193323Sed case XCore::COND_FALSE : return XCore::COND_TRUE; 164193323Sed } 165193323Sed} 166193323Sed 167193323Sed/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 168193323Sed/// true if it cannot be understood (e.g. it's a switch dispatch or isn't 169193323Sed/// implemented for a target). Upon success, this returns false and returns 170193323Sed/// with the following information in various cases: 171193323Sed/// 172193323Sed/// 1. If this block ends with no branches (it just falls through to its succ) 173193323Sed/// just return false, leaving TBB/FBB null. 174193323Sed/// 2. If this block ends with only an unconditional branch, it sets TBB to be 175193323Sed/// the destination block. 176193323Sed/// 3. If this block ends with an conditional branch and it falls through to 177193323Sed/// an successor block, it sets TBB to be the branch destination block and a 178193323Sed/// list of operands that evaluate the condition. These 179193323Sed/// operands can be passed to other TargetInstrInfo methods to create new 180193323Sed/// branches. 181193323Sed/// 4. If this block ends with an conditional branch and an unconditional 182193323Sed/// block, it returns the 'true' destination in TBB, the 'false' destination 183193323Sed/// in FBB, and a list of operands that evaluate the condition. These 184193323Sed/// operands can be passed to other TargetInstrInfo methods to create new 185193323Sed/// branches. 186193323Sed/// 187193323Sed/// Note that RemoveBranch and InsertBranch must be implemented to support 188193323Sed/// cases where this method returns success. 189193323Sed/// 190193323Sedbool 191193323SedXCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 192193323Sed MachineBasicBlock *&FBB, 193193323Sed SmallVectorImpl<MachineOperand> &Cond, 194193323Sed bool AllowModify) const { 195193323Sed // If the block has no terminators, it just falls into the block after it. 196193323Sed MachineBasicBlock::iterator I = MBB.end(); 197206083Srdivacky if (I == MBB.begin()) 198193323Sed return false; 199206083Srdivacky --I; 200206083Srdivacky while (I->isDebugValue()) { 201206083Srdivacky if (I == MBB.begin()) 202206083Srdivacky return false; 203206083Srdivacky --I; 204206083Srdivacky } 205206083Srdivacky if (!isUnpredicatedTerminator(I)) 206206083Srdivacky return false; 207193323Sed 208193323Sed // Get the last instruction in the block. 209193323Sed MachineInstr *LastInst = I; 210193323Sed 211193323Sed // If there is only one terminator instruction, process it. 212193323Sed if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 213193323Sed if (IsBRU(LastInst->getOpcode())) { 214193323Sed TBB = LastInst->getOperand(0).getMBB(); 215193323Sed return false; 216193323Sed } 217193323Sed 218193323Sed XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 219193323Sed if (BranchCode == XCore::COND_INVALID) 220193323Sed return true; // Can't handle indirect branch. 221193323Sed 222193323Sed // Conditional branch 223193323Sed // Block ends with fall-through condbranch. 224193323Sed 225193323Sed TBB = LastInst->getOperand(1).getMBB(); 226193323Sed Cond.push_back(MachineOperand::CreateImm(BranchCode)); 227193323Sed Cond.push_back(LastInst->getOperand(0)); 228193323Sed return false; 229193323Sed } 230193323Sed 231193323Sed // Get the instruction before it if it's a terminator. 232193323Sed MachineInstr *SecondLastInst = I; 233193323Sed 234193323Sed // If there are three terminators, we don't know what sort of block this is. 235193323Sed if (SecondLastInst && I != MBB.begin() && 236193323Sed isUnpredicatedTerminator(--I)) 237193323Sed return true; 238193323Sed 239193323Sed unsigned SecondLastOpc = SecondLastInst->getOpcode(); 240193323Sed XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 241193323Sed 242193323Sed // If the block ends with conditional branch followed by unconditional, 243193323Sed // handle it. 244193323Sed if (BranchCode != XCore::COND_INVALID 245193323Sed && IsBRU(LastInst->getOpcode())) { 246193323Sed 247193323Sed TBB = SecondLastInst->getOperand(1).getMBB(); 248193323Sed Cond.push_back(MachineOperand::CreateImm(BranchCode)); 249193323Sed Cond.push_back(SecondLastInst->getOperand(0)); 250193323Sed 251193323Sed FBB = LastInst->getOperand(0).getMBB(); 252193323Sed return false; 253193323Sed } 254193323Sed 255193323Sed // If the block ends with two unconditional branches, handle it. The second 256193323Sed // one is not executed, so remove it. 257193323Sed if (IsBRU(SecondLastInst->getOpcode()) && 258193323Sed IsBRU(LastInst->getOpcode())) { 259193323Sed TBB = SecondLastInst->getOperand(0).getMBB(); 260193323Sed I = LastInst; 261193323Sed if (AllowModify) 262193323Sed I->eraseFromParent(); 263193323Sed return false; 264193323Sed } 265193323Sed 266204642Srdivacky // Likewise if it ends with a branch table followed by an unconditional branch. 267204642Srdivacky if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) { 268204642Srdivacky I = LastInst; 269204642Srdivacky if (AllowModify) 270204642Srdivacky I->eraseFromParent(); 271204642Srdivacky return true; 272204642Srdivacky } 273204642Srdivacky 274193323Sed // Otherwise, can't handle this. 275193323Sed return true; 276193323Sed} 277193323Sed 278193323Sedunsigned 279193323SedXCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 280193323Sed MachineBasicBlock *FBB, 281210299Sed const SmallVectorImpl<MachineOperand> &Cond, 282210299Sed DebugLoc DL)const{ 283193323Sed // Shouldn't be a fall through. 284193323Sed assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 285193323Sed assert((Cond.size() == 2 || Cond.size() == 0) && 286193323Sed "Unexpected number of components!"); 287193323Sed 288193323Sed if (FBB == 0) { // One way branch. 289193323Sed if (Cond.empty()) { 290193323Sed // Unconditional branch 291210299Sed BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB); 292193323Sed } else { 293193323Sed // Conditional branch. 294193323Sed unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 295210299Sed BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 296193323Sed .addMBB(TBB); 297193323Sed } 298193323Sed return 1; 299193323Sed } 300193323Sed 301193323Sed // Two-way Conditional branch. 302193323Sed assert(Cond.size() == 2 && "Unexpected number of components!"); 303193323Sed unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 304210299Sed BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 305193323Sed .addMBB(TBB); 306210299Sed BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB); 307193323Sed return 2; 308193323Sed} 309193323Sed 310193323Sedunsigned 311193323SedXCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 312193323Sed MachineBasicBlock::iterator I = MBB.end(); 313193323Sed if (I == MBB.begin()) return 0; 314193323Sed --I; 315206083Srdivacky while (I->isDebugValue()) { 316206083Srdivacky if (I == MBB.begin()) 317206083Srdivacky return 0; 318206083Srdivacky --I; 319206083Srdivacky } 320193323Sed if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) 321193323Sed return 0; 322193323Sed 323193323Sed // Remove the branch. 324193323Sed I->eraseFromParent(); 325193323Sed 326193323Sed I = MBB.end(); 327193323Sed 328193323Sed if (I == MBB.begin()) return 1; 329193323Sed --I; 330193323Sed if (!IsCondBranch(I->getOpcode())) 331193323Sed return 1; 332193323Sed 333193323Sed // Remove the branch. 334193323Sed I->eraseFromParent(); 335193323Sed return 2; 336193323Sed} 337193323Sed 338210299Sedvoid XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 339210299Sed MachineBasicBlock::iterator I, DebugLoc DL, 340210299Sed unsigned DestReg, unsigned SrcReg, 341210299Sed bool KillSrc) const { 342210299Sed bool GRDest = XCore::GRRegsRegClass.contains(DestReg); 343210299Sed bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg); 344193323Sed 345210299Sed if (GRDest && GRSrc) { 346210299Sed BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg) 347210299Sed .addReg(SrcReg, getKillRegState(KillSrc)) 348210299Sed .addImm(0); 349210299Sed return; 350193323Sed } 351193323Sed 352210299Sed if (GRDest && SrcReg == XCore::SP) { 353210299Sed BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0); 354210299Sed return; 355193323Sed } 356210299Sed 357210299Sed if (DestReg == XCore::SP && GRSrc) { 358193323Sed BuildMI(MBB, I, DL, get(XCore::SETSP_1r)) 359210299Sed .addReg(SrcReg, getKillRegState(KillSrc)); 360210299Sed return; 361193323Sed } 362210299Sed llvm_unreachable("Impossible reg-to-reg copy"); 363193323Sed} 364193323Sed 365193323Sedvoid XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 366193323Sed MachineBasicBlock::iterator I, 367193323Sed unsigned SrcReg, bool isKill, 368193323Sed int FrameIndex, 369208599Srdivacky const TargetRegisterClass *RC, 370208599Srdivacky const TargetRegisterInfo *TRI) const 371193323Sed{ 372206124Srdivacky DebugLoc DL; 373193323Sed if (I != MBB.end()) DL = I->getDebugLoc(); 374193323Sed BuildMI(MBB, I, DL, get(XCore::STWFI)) 375193323Sed .addReg(SrcReg, getKillRegState(isKill)) 376193323Sed .addFrameIndex(FrameIndex) 377193323Sed .addImm(0); 378193323Sed} 379193323Sed 380193323Sedvoid XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 381193323Sed MachineBasicBlock::iterator I, 382193323Sed unsigned DestReg, int FrameIndex, 383208599Srdivacky const TargetRegisterClass *RC, 384208599Srdivacky const TargetRegisterInfo *TRI) const 385193323Sed{ 386206124Srdivacky DebugLoc DL; 387193323Sed if (I != MBB.end()) DL = I->getDebugLoc(); 388193323Sed BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) 389193323Sed .addFrameIndex(FrameIndex) 390193323Sed .addImm(0); 391193323Sed} 392193323Sed 393193323Sed/// ReverseBranchCondition - Return the inverse opcode of the 394193323Sed/// specified Branch instruction. 395193323Sedbool XCoreInstrInfo:: 396218893SdimReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 397193323Sed assert((Cond.size() == 2) && 398193323Sed "Invalid XCore branch condition!"); 399193323Sed Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); 400193323Sed return false; 401193323Sed} 402