1 //===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the XCore implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "XCoreInstrInfo.h" 15 #include "XCore.h" 16 #include "XCoreMachineFunctionInfo.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/TargetRegistry.h" 24 25 #define GET_INSTRINFO_CTOR 26 #include "XCoreGenInstrInfo.inc" 27 28 namespace llvm { 29 namespace XCore { 30 31 // XCore Condition Codes 32 enum CondCode { 33 COND_TRUE, 34 COND_FALSE, 35 COND_INVALID 36 }; 37 } 38 } 39 40 using namespace llvm; 41 42 XCoreInstrInfo::XCoreInstrInfo() 43 : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 44 RI(*this) { 45 } 46 47 static bool isZeroImm(const MachineOperand &op) { 48 return op.isImm() && op.getImm() == 0; 49 } 50 51 /// isLoadFromStackSlot - If the specified machine instruction is a direct 52 /// load from a stack slot, return the virtual or physical register number of 53 /// the destination along with the FrameIndex of the loaded stack slot. If 54 /// not, return 0. This predicate must return 0 if the instruction has 55 /// any side effects other than loading from the stack slot. 56 unsigned 57 XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{ 58 int Opcode = MI->getOpcode(); 59 if (Opcode == XCore::LDWFI) 60 { 61 if ((MI->getOperand(1).isFI()) && // is a stack slot 62 (MI->getOperand(2).isImm()) && // the imm is zero 63 (isZeroImm(MI->getOperand(2)))) 64 { 65 FrameIndex = MI->getOperand(1).getIndex(); 66 return MI->getOperand(0).getReg(); 67 } 68 } 69 return 0; 70 } 71 72 /// isStoreToStackSlot - If the specified machine instruction is a direct 73 /// store to a stack slot, return the virtual or physical register number of 74 /// the source reg along with the FrameIndex of the loaded stack slot. If 75 /// not, return 0. This predicate must return 0 if the instruction has 76 /// any side effects other than storing to the stack slot. 77 unsigned 78 XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 79 int &FrameIndex) const { 80 int Opcode = MI->getOpcode(); 81 if (Opcode == XCore::STWFI) 82 { 83 if ((MI->getOperand(1).isFI()) && // is a stack slot 84 (MI->getOperand(2).isImm()) && // the imm is zero 85 (isZeroImm(MI->getOperand(2)))) 86 { 87 FrameIndex = MI->getOperand(1).getIndex(); 88 return MI->getOperand(0).getReg(); 89 } 90 } 91 return 0; 92 } 93 94 //===----------------------------------------------------------------------===// 95 // Branch Analysis 96 //===----------------------------------------------------------------------===// 97 98 static inline bool IsBRU(unsigned BrOpc) { 99 return BrOpc == XCore::BRFU_u6 100 || BrOpc == XCore::BRFU_lu6 101 || BrOpc == XCore::BRBU_u6 102 || BrOpc == XCore::BRBU_lu6; 103 } 104 105 static inline bool IsBRT(unsigned BrOpc) { 106 return BrOpc == XCore::BRFT_ru6 107 || BrOpc == XCore::BRFT_lru6 108 || BrOpc == XCore::BRBT_ru6 109 || BrOpc == XCore::BRBT_lru6; 110 } 111 112 static inline bool IsBRF(unsigned BrOpc) { 113 return BrOpc == XCore::BRFF_ru6 114 || BrOpc == XCore::BRFF_lru6 115 || BrOpc == XCore::BRBF_ru6 116 || BrOpc == XCore::BRBF_lru6; 117 } 118 119 static inline bool IsCondBranch(unsigned BrOpc) { 120 return IsBRF(BrOpc) || IsBRT(BrOpc); 121 } 122 123 static inline bool IsBR_JT(unsigned BrOpc) { 124 return BrOpc == XCore::BR_JT 125 || BrOpc == XCore::BR_JT32; 126 } 127 128 /// GetCondFromBranchOpc - Return the XCore CC that matches 129 /// the correspondent Branch instruction opcode. 130 static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) 131 { 132 if (IsBRT(BrOpc)) { 133 return XCore::COND_TRUE; 134 } else if (IsBRF(BrOpc)) { 135 return XCore::COND_FALSE; 136 } else { 137 return XCore::COND_INVALID; 138 } 139 } 140 141 /// GetCondBranchFromCond - Return the Branch instruction 142 /// opcode that matches the cc. 143 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) 144 { 145 switch (CC) { 146 default: llvm_unreachable("Illegal condition code!"); 147 case XCore::COND_TRUE : return XCore::BRFT_lru6; 148 case XCore::COND_FALSE : return XCore::BRFF_lru6; 149 } 150 } 151 152 /// GetOppositeBranchCondition - Return the inverse of the specified 153 /// condition, e.g. turning COND_E to COND_NE. 154 static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) 155 { 156 switch (CC) { 157 default: llvm_unreachable("Illegal condition code!"); 158 case XCore::COND_TRUE : return XCore::COND_FALSE; 159 case XCore::COND_FALSE : return XCore::COND_TRUE; 160 } 161 } 162 163 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 164 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't 165 /// implemented for a target). Upon success, this returns false and returns 166 /// with the following information in various cases: 167 /// 168 /// 1. If this block ends with no branches (it just falls through to its succ) 169 /// just return false, leaving TBB/FBB null. 170 /// 2. If this block ends with only an unconditional branch, it sets TBB to be 171 /// the destination block. 172 /// 3. If this block ends with an conditional branch and it falls through to 173 /// an successor block, it sets TBB to be the branch destination block and a 174 /// list of operands that evaluate the condition. These 175 /// operands can be passed to other TargetInstrInfo methods to create new 176 /// branches. 177 /// 4. If this block ends with an conditional branch and an unconditional 178 /// block, it returns the 'true' destination in TBB, the 'false' destination 179 /// in FBB, and a list of operands that evaluate the condition. These 180 /// operands can be passed to other TargetInstrInfo methods to create new 181 /// branches. 182 /// 183 /// Note that RemoveBranch and InsertBranch must be implemented to support 184 /// cases where this method returns success. 185 /// 186 bool 187 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 188 MachineBasicBlock *&FBB, 189 SmallVectorImpl<MachineOperand> &Cond, 190 bool AllowModify) const { 191 // If the block has no terminators, it just falls into the block after it. 192 MachineBasicBlock::iterator I = MBB.end(); 193 if (I == MBB.begin()) 194 return false; 195 --I; 196 while (I->isDebugValue()) { 197 if (I == MBB.begin()) 198 return false; 199 --I; 200 } 201 if (!isUnpredicatedTerminator(I)) 202 return false; 203 204 // Get the last instruction in the block. 205 MachineInstr *LastInst = I; 206 207 // If there is only one terminator instruction, process it. 208 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 209 if (IsBRU(LastInst->getOpcode())) { 210 TBB = LastInst->getOperand(0).getMBB(); 211 return false; 212 } 213 214 XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 215 if (BranchCode == XCore::COND_INVALID) 216 return true; // Can't handle indirect branch. 217 218 // Conditional branch 219 // Block ends with fall-through condbranch. 220 221 TBB = LastInst->getOperand(1).getMBB(); 222 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 223 Cond.push_back(LastInst->getOperand(0)); 224 return false; 225 } 226 227 // Get the instruction before it if it's a terminator. 228 MachineInstr *SecondLastInst = I; 229 230 // If there are three terminators, we don't know what sort of block this is. 231 if (SecondLastInst && I != MBB.begin() && 232 isUnpredicatedTerminator(--I)) 233 return true; 234 235 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 236 XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 237 238 // If the block ends with conditional branch followed by unconditional, 239 // handle it. 240 if (BranchCode != XCore::COND_INVALID 241 && IsBRU(LastInst->getOpcode())) { 242 243 TBB = SecondLastInst->getOperand(1).getMBB(); 244 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 245 Cond.push_back(SecondLastInst->getOperand(0)); 246 247 FBB = LastInst->getOperand(0).getMBB(); 248 return false; 249 } 250 251 // If the block ends with two unconditional branches, handle it. The second 252 // one is not executed, so remove it. 253 if (IsBRU(SecondLastInst->getOpcode()) && 254 IsBRU(LastInst->getOpcode())) { 255 TBB = SecondLastInst->getOperand(0).getMBB(); 256 I = LastInst; 257 if (AllowModify) 258 I->eraseFromParent(); 259 return false; 260 } 261 262 // Likewise if it ends with a branch table followed by an unconditional branch. 263 if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) { 264 I = LastInst; 265 if (AllowModify) 266 I->eraseFromParent(); 267 return true; 268 } 269 270 // Otherwise, can't handle this. 271 return true; 272 } 273 274 unsigned 275 XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 276 MachineBasicBlock *FBB, 277 const SmallVectorImpl<MachineOperand> &Cond, 278 DebugLoc DL)const{ 279 // Shouldn't be a fall through. 280 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 281 assert((Cond.size() == 2 || Cond.size() == 0) && 282 "Unexpected number of components!"); 283 284 if (FBB == 0) { // One way branch. 285 if (Cond.empty()) { 286 // Unconditional branch 287 BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB); 288 } else { 289 // Conditional branch. 290 unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 291 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 292 .addMBB(TBB); 293 } 294 return 1; 295 } 296 297 // Two-way Conditional branch. 298 assert(Cond.size() == 2 && "Unexpected number of components!"); 299 unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 300 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 301 .addMBB(TBB); 302 BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB); 303 return 2; 304 } 305 306 unsigned 307 XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 308 MachineBasicBlock::iterator I = MBB.end(); 309 if (I == MBB.begin()) return 0; 310 --I; 311 while (I->isDebugValue()) { 312 if (I == MBB.begin()) 313 return 0; 314 --I; 315 } 316 if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) 317 return 0; 318 319 // Remove the branch. 320 I->eraseFromParent(); 321 322 I = MBB.end(); 323 324 if (I == MBB.begin()) return 1; 325 --I; 326 if (!IsCondBranch(I->getOpcode())) 327 return 1; 328 329 // Remove the branch. 330 I->eraseFromParent(); 331 return 2; 332 } 333 334 void XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 335 MachineBasicBlock::iterator I, DebugLoc DL, 336 unsigned DestReg, unsigned SrcReg, 337 bool KillSrc) const { 338 bool GRDest = XCore::GRRegsRegClass.contains(DestReg); 339 bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg); 340 341 if (GRDest && GRSrc) { 342 BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg) 343 .addReg(SrcReg, getKillRegState(KillSrc)) 344 .addImm(0); 345 return; 346 } 347 348 if (GRDest && SrcReg == XCore::SP) { 349 BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0); 350 return; 351 } 352 353 if (DestReg == XCore::SP && GRSrc) { 354 BuildMI(MBB, I, DL, get(XCore::SETSP_1r)) 355 .addReg(SrcReg, getKillRegState(KillSrc)); 356 return; 357 } 358 llvm_unreachable("Impossible reg-to-reg copy"); 359 } 360 361 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 362 MachineBasicBlock::iterator I, 363 unsigned SrcReg, bool isKill, 364 int FrameIndex, 365 const TargetRegisterClass *RC, 366 const TargetRegisterInfo *TRI) const 367 { 368 DebugLoc DL; 369 if (I != MBB.end()) DL = I->getDebugLoc(); 370 BuildMI(MBB, I, DL, get(XCore::STWFI)) 371 .addReg(SrcReg, getKillRegState(isKill)) 372 .addFrameIndex(FrameIndex) 373 .addImm(0); 374 } 375 376 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 377 MachineBasicBlock::iterator I, 378 unsigned DestReg, int FrameIndex, 379 const TargetRegisterClass *RC, 380 const TargetRegisterInfo *TRI) const 381 { 382 DebugLoc DL; 383 if (I != MBB.end()) DL = I->getDebugLoc(); 384 BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) 385 .addFrameIndex(FrameIndex) 386 .addImm(0); 387 } 388 389 MachineInstr* 390 XCoreInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, 391 uint64_t Offset, const MDNode *MDPtr, 392 DebugLoc DL) const { 393 MachineInstrBuilder MIB = BuildMI(MF, DL, get(XCore::DBG_VALUE)) 394 .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); 395 return &*MIB; 396 } 397 398 /// ReverseBranchCondition - Return the inverse opcode of the 399 /// specified Branch instruction. 400 bool XCoreInstrInfo:: 401 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 402 assert((Cond.size() == 2) && 403 "Invalid XCore branch condition!"); 404 Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); 405 return false; 406 } 407