LLVM API Documentation
00001 //===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the XCore implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "XCoreInstrInfo.h" 00015 #include "XCore.h" 00016 #include "XCoreMachineFunctionInfo.h" 00017 #include "llvm/ADT/STLExtras.h" 00018 #include "llvm/CodeGen/MachineConstantPool.h" 00019 #include "llvm/CodeGen/MachineFrameInfo.h" 00020 #include "llvm/CodeGen/MachineInstrBuilder.h" 00021 #include "llvm/CodeGen/MachineMemOperand.h" 00022 #include "llvm/IR/Constants.h" 00023 #include "llvm/IR/Function.h" 00024 #include "llvm/MC/MCContext.h" 00025 #include "llvm/Support/Debug.h" 00026 #include "llvm/Support/ErrorHandling.h" 00027 #include "llvm/Support/TargetRegistry.h" 00028 00029 using namespace llvm; 00030 00031 #define GET_INSTRINFO_CTOR_DTOR 00032 #include "XCoreGenInstrInfo.inc" 00033 00034 namespace llvm { 00035 namespace XCore { 00036 00037 // XCore Condition Codes 00038 enum CondCode { 00039 COND_TRUE, 00040 COND_FALSE, 00041 COND_INVALID 00042 }; 00043 } 00044 } 00045 00046 // Pin the vtable to this file. 00047 void XCoreInstrInfo::anchor() {} 00048 00049 XCoreInstrInfo::XCoreInstrInfo() 00050 : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 00051 RI() { 00052 } 00053 00054 static bool isZeroImm(const MachineOperand &op) { 00055 return op.isImm() && op.getImm() == 0; 00056 } 00057 00058 /// isLoadFromStackSlot - If the specified machine instruction is a direct 00059 /// load from a stack slot, return the virtual or physical register number of 00060 /// the destination along with the FrameIndex of the loaded stack slot. If 00061 /// not, return 0. This predicate must return 0 if the instruction has 00062 /// any side effects other than loading from the stack slot. 00063 unsigned 00064 XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{ 00065 int Opcode = MI->getOpcode(); 00066 if (Opcode == XCore::LDWFI) 00067 { 00068 if ((MI->getOperand(1).isFI()) && // is a stack slot 00069 (MI->getOperand(2).isImm()) && // the imm is zero 00070 (isZeroImm(MI->getOperand(2)))) 00071 { 00072 FrameIndex = MI->getOperand(1).getIndex(); 00073 return MI->getOperand(0).getReg(); 00074 } 00075 } 00076 return 0; 00077 } 00078 00079 /// isStoreToStackSlot - If the specified machine instruction is a direct 00080 /// store to a stack slot, return the virtual or physical register number of 00081 /// the source reg along with the FrameIndex of the loaded stack slot. If 00082 /// not, return 0. This predicate must return 0 if the instruction has 00083 /// any side effects other than storing to the stack slot. 00084 unsigned 00085 XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 00086 int &FrameIndex) const { 00087 int Opcode = MI->getOpcode(); 00088 if (Opcode == XCore::STWFI) 00089 { 00090 if ((MI->getOperand(1).isFI()) && // is a stack slot 00091 (MI->getOperand(2).isImm()) && // the imm is zero 00092 (isZeroImm(MI->getOperand(2)))) 00093 { 00094 FrameIndex = MI->getOperand(1).getIndex(); 00095 return MI->getOperand(0).getReg(); 00096 } 00097 } 00098 return 0; 00099 } 00100 00101 //===----------------------------------------------------------------------===// 00102 // Branch Analysis 00103 //===----------------------------------------------------------------------===// 00104 00105 static inline bool IsBRU(unsigned BrOpc) { 00106 return BrOpc == XCore::BRFU_u6 00107 || BrOpc == XCore::BRFU_lu6 00108 || BrOpc == XCore::BRBU_u6 00109 || BrOpc == XCore::BRBU_lu6; 00110 } 00111 00112 static inline bool IsBRT(unsigned BrOpc) { 00113 return BrOpc == XCore::BRFT_ru6 00114 || BrOpc == XCore::BRFT_lru6 00115 || BrOpc == XCore::BRBT_ru6 00116 || BrOpc == XCore::BRBT_lru6; 00117 } 00118 00119 static inline bool IsBRF(unsigned BrOpc) { 00120 return BrOpc == XCore::BRFF_ru6 00121 || BrOpc == XCore::BRFF_lru6 00122 || BrOpc == XCore::BRBF_ru6 00123 || BrOpc == XCore::BRBF_lru6; 00124 } 00125 00126 static inline bool IsCondBranch(unsigned BrOpc) { 00127 return IsBRF(BrOpc) || IsBRT(BrOpc); 00128 } 00129 00130 static inline bool IsBR_JT(unsigned BrOpc) { 00131 return BrOpc == XCore::BR_JT 00132 || BrOpc == XCore::BR_JT32; 00133 } 00134 00135 /// GetCondFromBranchOpc - Return the XCore CC that matches 00136 /// the correspondent Branch instruction opcode. 00137 static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) 00138 { 00139 if (IsBRT(BrOpc)) { 00140 return XCore::COND_TRUE; 00141 } else if (IsBRF(BrOpc)) { 00142 return XCore::COND_FALSE; 00143 } else { 00144 return XCore::COND_INVALID; 00145 } 00146 } 00147 00148 /// GetCondBranchFromCond - Return the Branch instruction 00149 /// opcode that matches the cc. 00150 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) 00151 { 00152 switch (CC) { 00153 default: llvm_unreachable("Illegal condition code!"); 00154 case XCore::COND_TRUE : return XCore::BRFT_lru6; 00155 case XCore::COND_FALSE : return XCore::BRFF_lru6; 00156 } 00157 } 00158 00159 /// GetOppositeBranchCondition - Return the inverse of the specified 00160 /// condition, e.g. turning COND_E to COND_NE. 00161 static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) 00162 { 00163 switch (CC) { 00164 default: llvm_unreachable("Illegal condition code!"); 00165 case XCore::COND_TRUE : return XCore::COND_FALSE; 00166 case XCore::COND_FALSE : return XCore::COND_TRUE; 00167 } 00168 } 00169 00170 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 00171 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't 00172 /// implemented for a target). Upon success, this returns false and returns 00173 /// with the following information in various cases: 00174 /// 00175 /// 1. If this block ends with no branches (it just falls through to its succ) 00176 /// just return false, leaving TBB/FBB null. 00177 /// 2. If this block ends with only an unconditional branch, it sets TBB to be 00178 /// the destination block. 00179 /// 3. If this block ends with an conditional branch and it falls through to 00180 /// an successor block, it sets TBB to be the branch destination block and a 00181 /// list of operands that evaluate the condition. These 00182 /// operands can be passed to other TargetInstrInfo methods to create new 00183 /// branches. 00184 /// 4. If this block ends with an conditional branch and an unconditional 00185 /// block, it returns the 'true' destination in TBB, the 'false' destination 00186 /// in FBB, and a list of operands that evaluate the condition. These 00187 /// operands can be passed to other TargetInstrInfo methods to create new 00188 /// branches. 00189 /// 00190 /// Note that RemoveBranch and InsertBranch must be implemented to support 00191 /// cases where this method returns success. 00192 /// 00193 bool 00194 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 00195 MachineBasicBlock *&FBB, 00196 SmallVectorImpl<MachineOperand> &Cond, 00197 bool AllowModify) const { 00198 // If the block has no terminators, it just falls into the block after it. 00199 MachineBasicBlock::iterator I = MBB.end(); 00200 if (I == MBB.begin()) 00201 return false; 00202 --I; 00203 while (I->isDebugValue()) { 00204 if (I == MBB.begin()) 00205 return false; 00206 --I; 00207 } 00208 if (!isUnpredicatedTerminator(I)) 00209 return false; 00210 00211 // Get the last instruction in the block. 00212 MachineInstr *LastInst = I; 00213 00214 // If there is only one terminator instruction, process it. 00215 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 00216 if (IsBRU(LastInst->getOpcode())) { 00217 TBB = LastInst->getOperand(0).getMBB(); 00218 return false; 00219 } 00220 00221 XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 00222 if (BranchCode == XCore::COND_INVALID) 00223 return true; // Can't handle indirect branch. 00224 00225 // Conditional branch 00226 // Block ends with fall-through condbranch. 00227 00228 TBB = LastInst->getOperand(1).getMBB(); 00229 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 00230 Cond.push_back(LastInst->getOperand(0)); 00231 return false; 00232 } 00233 00234 // Get the instruction before it if it's a terminator. 00235 MachineInstr *SecondLastInst = I; 00236 00237 // If there are three terminators, we don't know what sort of block this is. 00238 if (SecondLastInst && I != MBB.begin() && 00239 isUnpredicatedTerminator(--I)) 00240 return true; 00241 00242 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 00243 XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 00244 00245 // If the block ends with conditional branch followed by unconditional, 00246 // handle it. 00247 if (BranchCode != XCore::COND_INVALID 00248 && IsBRU(LastInst->getOpcode())) { 00249 00250 TBB = SecondLastInst->getOperand(1).getMBB(); 00251 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 00252 Cond.push_back(SecondLastInst->getOperand(0)); 00253 00254 FBB = LastInst->getOperand(0).getMBB(); 00255 return false; 00256 } 00257 00258 // If the block ends with two unconditional branches, handle it. The second 00259 // one is not executed, so remove it. 00260 if (IsBRU(SecondLastInst->getOpcode()) && 00261 IsBRU(LastInst->getOpcode())) { 00262 TBB = SecondLastInst->getOperand(0).getMBB(); 00263 I = LastInst; 00264 if (AllowModify) 00265 I->eraseFromParent(); 00266 return false; 00267 } 00268 00269 // Likewise if it ends with a branch table followed by an unconditional branch. 00270 if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) { 00271 I = LastInst; 00272 if (AllowModify) 00273 I->eraseFromParent(); 00274 return true; 00275 } 00276 00277 // Otherwise, can't handle this. 00278 return true; 00279 } 00280 00281 unsigned 00282 XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 00283 MachineBasicBlock *FBB, 00284 const SmallVectorImpl<MachineOperand> &Cond, 00285 DebugLoc DL)const{ 00286 // Shouldn't be a fall through. 00287 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 00288 assert((Cond.size() == 2 || Cond.size() == 0) && 00289 "Unexpected number of components!"); 00290 00291 if (!FBB) { // One way branch. 00292 if (Cond.empty()) { 00293 // Unconditional branch 00294 BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB); 00295 } else { 00296 // Conditional branch. 00297 unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 00298 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 00299 .addMBB(TBB); 00300 } 00301 return 1; 00302 } 00303 00304 // Two-way Conditional branch. 00305 assert(Cond.size() == 2 && "Unexpected number of components!"); 00306 unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 00307 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 00308 .addMBB(TBB); 00309 BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB); 00310 return 2; 00311 } 00312 00313 unsigned 00314 XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 00315 MachineBasicBlock::iterator I = MBB.end(); 00316 if (I == MBB.begin()) return 0; 00317 --I; 00318 while (I->isDebugValue()) { 00319 if (I == MBB.begin()) 00320 return 0; 00321 --I; 00322 } 00323 if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) 00324 return 0; 00325 00326 // Remove the branch. 00327 I->eraseFromParent(); 00328 00329 I = MBB.end(); 00330 00331 if (I == MBB.begin()) return 1; 00332 --I; 00333 if (!IsCondBranch(I->getOpcode())) 00334 return 1; 00335 00336 // Remove the branch. 00337 I->eraseFromParent(); 00338 return 2; 00339 } 00340 00341 void XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 00342 MachineBasicBlock::iterator I, DebugLoc DL, 00343 unsigned DestReg, unsigned SrcReg, 00344 bool KillSrc) const { 00345 bool GRDest = XCore::GRRegsRegClass.contains(DestReg); 00346 bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg); 00347 00348 if (GRDest && GRSrc) { 00349 BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg) 00350 .addReg(SrcReg, getKillRegState(KillSrc)) 00351 .addImm(0); 00352 return; 00353 } 00354 00355 if (GRDest && SrcReg == XCore::SP) { 00356 BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0); 00357 return; 00358 } 00359 00360 if (DestReg == XCore::SP && GRSrc) { 00361 BuildMI(MBB, I, DL, get(XCore::SETSP_1r)) 00362 .addReg(SrcReg, getKillRegState(KillSrc)); 00363 return; 00364 } 00365 llvm_unreachable("Impossible reg-to-reg copy"); 00366 } 00367 00368 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 00369 MachineBasicBlock::iterator I, 00370 unsigned SrcReg, bool isKill, 00371 int FrameIndex, 00372 const TargetRegisterClass *RC, 00373 const TargetRegisterInfo *TRI) const 00374 { 00375 DebugLoc DL; 00376 if (I != MBB.end() && !I->isDebugValue()) 00377 DL = I->getDebugLoc(); 00378 MachineFunction *MF = MBB.getParent(); 00379 const MachineFrameInfo &MFI = *MF->getFrameInfo(); 00380 MachineMemOperand *MMO = 00381 MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), 00382 MachineMemOperand::MOStore, 00383 MFI.getObjectSize(FrameIndex), 00384 MFI.getObjectAlignment(FrameIndex)); 00385 BuildMI(MBB, I, DL, get(XCore::STWFI)) 00386 .addReg(SrcReg, getKillRegState(isKill)) 00387 .addFrameIndex(FrameIndex) 00388 .addImm(0) 00389 .addMemOperand(MMO); 00390 } 00391 00392 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 00393 MachineBasicBlock::iterator I, 00394 unsigned DestReg, int FrameIndex, 00395 const TargetRegisterClass *RC, 00396 const TargetRegisterInfo *TRI) const 00397 { 00398 DebugLoc DL; 00399 if (I != MBB.end() && !I->isDebugValue()) 00400 DL = I->getDebugLoc(); 00401 MachineFunction *MF = MBB.getParent(); 00402 const MachineFrameInfo &MFI = *MF->getFrameInfo(); 00403 MachineMemOperand *MMO = 00404 MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), 00405 MachineMemOperand::MOLoad, 00406 MFI.getObjectSize(FrameIndex), 00407 MFI.getObjectAlignment(FrameIndex)); 00408 BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) 00409 .addFrameIndex(FrameIndex) 00410 .addImm(0) 00411 .addMemOperand(MMO); 00412 } 00413 00414 /// ReverseBranchCondition - Return the inverse opcode of the 00415 /// specified Branch instruction. 00416 bool XCoreInstrInfo:: 00417 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 00418 assert((Cond.size() == 2) && 00419 "Invalid XCore branch condition!"); 00420 Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); 00421 return false; 00422 } 00423 00424 static inline bool isImmU6(unsigned val) { 00425 return val < (1 << 6); 00426 } 00427 00428 static inline bool isImmU16(unsigned val) { 00429 return val < (1 << 16); 00430 } 00431 00432 static bool isImmMskBitp(unsigned val) { 00433 if (!isMask_32(val)) { 00434 return false; 00435 } 00436 int N = Log2_32(val) + 1; 00437 return (N >= 1 && N <= 8) || N == 16 || N == 24 || N == 32; 00438 } 00439 00440 MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate( 00441 MachineBasicBlock &MBB, 00442 MachineBasicBlock::iterator MI, 00443 unsigned Reg, uint64_t Value) const { 00444 DebugLoc dl; 00445 if (MI != MBB.end() && !MI->isDebugValue()) 00446 dl = MI->getDebugLoc(); 00447 if (isImmMskBitp(Value)) { 00448 int N = Log2_32(Value) + 1; 00449 return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg).addImm(N); 00450 } 00451 if (isImmU16(Value)) { 00452 int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 00453 return BuildMI(MBB, MI, dl, get(Opcode), Reg).addImm(Value); 00454 } 00455 MachineConstantPool *ConstantPool = MBB.getParent()->getConstantPool(); 00456 const Constant *C = ConstantInt::get( 00457 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Value); 00458 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 00459 return BuildMI(MBB, MI, dl, get(XCore::LDWCP_lru6), Reg) 00460 .addConstantPoolIndex(Idx); 00461 }