LLVM API Documentation
00001 //===-- MBlazeInstrInfo.cpp - MBlaze 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 MBlaze implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "MBlazeInstrInfo.h" 00015 #include "MBlazeMachineFunction.h" 00016 #include "MBlazeTargetMachine.h" 00017 #include "llvm/ADT/STLExtras.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 #include "llvm/CodeGen/MachineRegisterInfo.h" 00020 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" 00021 #include "llvm/Support/CommandLine.h" 00022 #include "llvm/Support/ErrorHandling.h" 00023 #include "llvm/Support/TargetRegistry.h" 00024 00025 #define GET_INSTRINFO_CTOR 00026 #include "MBlazeGenInstrInfo.inc" 00027 00028 using namespace llvm; 00029 00030 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm) 00031 : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP), 00032 TM(tm), RI(*TM.getSubtargetImpl(), *this) {} 00033 00034 static bool isZeroImm(const MachineOperand &op) { 00035 return op.isImm() && op.getImm() == 0; 00036 } 00037 00038 /// isLoadFromStackSlot - If the specified machine instruction is a direct 00039 /// load from a stack slot, return the virtual or physical register number of 00040 /// the destination along with the FrameIndex of the loaded stack slot. If 00041 /// not, return 0. This predicate must return 0 if the instruction has 00042 /// any side effects other than loading from the stack slot. 00043 unsigned MBlazeInstrInfo:: 00044 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { 00045 if (MI->getOpcode() == MBlaze::LWI) { 00046 if ((MI->getOperand(1).isFI()) && // is a stack slot 00047 (MI->getOperand(2).isImm()) && // the imm is zero 00048 (isZeroImm(MI->getOperand(2)))) { 00049 FrameIndex = MI->getOperand(1).getIndex(); 00050 return MI->getOperand(0).getReg(); 00051 } 00052 } 00053 00054 return 0; 00055 } 00056 00057 /// isStoreToStackSlot - If the specified machine instruction is a direct 00058 /// store to a stack slot, return the virtual or physical register number of 00059 /// the source reg along with the FrameIndex of the loaded stack slot. If 00060 /// not, return 0. This predicate must return 0 if the instruction has 00061 /// any side effects other than storing to the stack slot. 00062 unsigned MBlazeInstrInfo:: 00063 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { 00064 if (MI->getOpcode() == MBlaze::SWI) { 00065 if ((MI->getOperand(1).isFI()) && // is a stack slot 00066 (MI->getOperand(2).isImm()) && // the imm is zero 00067 (isZeroImm(MI->getOperand(2)))) { 00068 FrameIndex = MI->getOperand(1).getIndex(); 00069 return MI->getOperand(0).getReg(); 00070 } 00071 } 00072 return 0; 00073 } 00074 00075 /// insertNoop - If data hazard condition is found insert the target nop 00076 /// instruction. 00077 void MBlazeInstrInfo:: 00078 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { 00079 DebugLoc DL; 00080 BuildMI(MBB, MI, DL, get(MBlaze::NOP)); 00081 } 00082 00083 void MBlazeInstrInfo:: 00084 copyPhysReg(MachineBasicBlock &MBB, 00085 MachineBasicBlock::iterator I, DebugLoc DL, 00086 unsigned DestReg, unsigned SrcReg, 00087 bool KillSrc) const { 00088 llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg) 00089 .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0); 00090 } 00091 00092 void MBlazeInstrInfo:: 00093 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00094 unsigned SrcReg, bool isKill, int FI, 00095 const TargetRegisterClass *RC, 00096 const TargetRegisterInfo *TRI) const { 00097 DebugLoc DL; 00098 BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill)) 00099 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 00100 } 00101 00102 void MBlazeInstrInfo:: 00103 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00104 unsigned DestReg, int FI, 00105 const TargetRegisterClass *RC, 00106 const TargetRegisterInfo *TRI) const { 00107 DebugLoc DL; 00108 BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg) 00109 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 00110 } 00111 00112 //===----------------------------------------------------------------------===// 00113 // Branch Analysis 00114 //===----------------------------------------------------------------------===// 00115 bool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 00116 MachineBasicBlock *&TBB, 00117 MachineBasicBlock *&FBB, 00118 SmallVectorImpl<MachineOperand> &Cond, 00119 bool AllowModify) const { 00120 // If the block has no terminators, it just falls into the block after it. 00121 MachineBasicBlock::iterator I = MBB.end(); 00122 if (I == MBB.begin()) 00123 return false; 00124 --I; 00125 while (I->isDebugValue()) { 00126 if (I == MBB.begin()) 00127 return false; 00128 --I; 00129 } 00130 if (!isUnpredicatedTerminator(I)) 00131 return false; 00132 00133 // Get the last instruction in the block. 00134 MachineInstr *LastInst = I; 00135 00136 // If there is only one terminator instruction, process it. 00137 unsigned LastOpc = LastInst->getOpcode(); 00138 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 00139 if (MBlaze::isUncondBranchOpcode(LastOpc)) { 00140 TBB = LastInst->getOperand(0).getMBB(); 00141 return false; 00142 } 00143 if (MBlaze::isCondBranchOpcode(LastOpc)) { 00144 // Block ends with fall-through condbranch. 00145 TBB = LastInst->getOperand(1).getMBB(); 00146 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 00147 Cond.push_back(LastInst->getOperand(0)); 00148 return false; 00149 } 00150 // Otherwise, don't know what this is. 00151 return true; 00152 } 00153 00154 // Get the instruction before it if it's a terminator. 00155 MachineInstr *SecondLastInst = I; 00156 00157 // If there are three terminators, we don't know what sort of block this is. 00158 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 00159 return true; 00160 00161 // If the block ends with something like BEQID then BRID, handle it. 00162 if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) && 00163 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 00164 TBB = SecondLastInst->getOperand(1).getMBB(); 00165 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode())); 00166 Cond.push_back(SecondLastInst->getOperand(0)); 00167 FBB = LastInst->getOperand(0).getMBB(); 00168 return false; 00169 } 00170 00171 // If the block ends with two unconditional branches, handle it. 00172 // The second one is not executed, so remove it. 00173 if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) && 00174 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 00175 TBB = SecondLastInst->getOperand(0).getMBB(); 00176 I = LastInst; 00177 if (AllowModify) 00178 I->eraseFromParent(); 00179 return false; 00180 } 00181 00182 // Otherwise, can't handle this. 00183 return true; 00184 } 00185 00186 unsigned MBlazeInstrInfo:: 00187 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 00188 MachineBasicBlock *FBB, 00189 const SmallVectorImpl<MachineOperand> &Cond, 00190 DebugLoc DL) const { 00191 // Shouldn't be a fall through. 00192 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 00193 assert((Cond.size() == 2 || Cond.size() == 0) && 00194 "MBlaze branch conditions have two components!"); 00195 00196 unsigned Opc = MBlaze::BRID; 00197 if (!Cond.empty()) 00198 Opc = (unsigned)Cond[0].getImm(); 00199 00200 if (FBB == 0) { 00201 if (Cond.empty()) // Unconditional branch 00202 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB); 00203 else // Conditional branch 00204 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 00205 return 1; 00206 } 00207 00208 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 00209 BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB); 00210 return 2; 00211 } 00212 00213 unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 00214 MachineBasicBlock::iterator I = MBB.end(); 00215 if (I == MBB.begin()) return 0; 00216 --I; 00217 while (I->isDebugValue()) { 00218 if (I == MBB.begin()) 00219 return 0; 00220 --I; 00221 } 00222 00223 if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) && 00224 !MBlaze::isCondBranchOpcode(I->getOpcode())) 00225 return 0; 00226 00227 // Remove the branch. 00228 I->eraseFromParent(); 00229 00230 I = MBB.end(); 00231 00232 if (I == MBB.begin()) return 1; 00233 --I; 00234 if (!MBlaze::isCondBranchOpcode(I->getOpcode())) 00235 return 1; 00236 00237 // Remove the branch. 00238 I->eraseFromParent(); 00239 return 2; 00240 } 00241 00242 bool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> 00243 &Cond) const { 00244 assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!"); 00245 switch (Cond[0].getImm()) { 00246 default: return true; 00247 case MBlaze::BEQ: Cond[0].setImm(MBlaze::BNE); return false; 00248 case MBlaze::BNE: Cond[0].setImm(MBlaze::BEQ); return false; 00249 case MBlaze::BGT: Cond[0].setImm(MBlaze::BLE); return false; 00250 case MBlaze::BGE: Cond[0].setImm(MBlaze::BLT); return false; 00251 case MBlaze::BLT: Cond[0].setImm(MBlaze::BGE); return false; 00252 case MBlaze::BLE: Cond[0].setImm(MBlaze::BGT); return false; 00253 case MBlaze::BEQI: Cond[0].setImm(MBlaze::BNEI); return false; 00254 case MBlaze::BNEI: Cond[0].setImm(MBlaze::BEQI); return false; 00255 case MBlaze::BGTI: Cond[0].setImm(MBlaze::BLEI); return false; 00256 case MBlaze::BGEI: Cond[0].setImm(MBlaze::BLTI); return false; 00257 case MBlaze::BLTI: Cond[0].setImm(MBlaze::BGEI); return false; 00258 case MBlaze::BLEI: Cond[0].setImm(MBlaze::BGTI); return false; 00259 case MBlaze::BEQD: Cond[0].setImm(MBlaze::BNED); return false; 00260 case MBlaze::BNED: Cond[0].setImm(MBlaze::BEQD); return false; 00261 case MBlaze::BGTD: Cond[0].setImm(MBlaze::BLED); return false; 00262 case MBlaze::BGED: Cond[0].setImm(MBlaze::BLTD); return false; 00263 case MBlaze::BLTD: Cond[0].setImm(MBlaze::BGED); return false; 00264 case MBlaze::BLED: Cond[0].setImm(MBlaze::BGTD); return false; 00265 case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false; 00266 case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false; 00267 case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false; 00268 case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false; 00269 case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false; 00270 case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false; 00271 } 00272 } 00273 00274 /// getGlobalBaseReg - Return a virtual register initialized with the 00275 /// the global base register value. Output instructions required to 00276 /// initialize the register in the function entry block, if necessary. 00277 /// 00278 unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 00279 MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>(); 00280 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg(); 00281 if (GlobalBaseReg != 0) 00282 return GlobalBaseReg; 00283 00284 // Insert the set of GlobalBaseReg into the first MBB of the function 00285 MachineBasicBlock &FirstMBB = MF->front(); 00286 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 00287 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 00288 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 00289 00290 GlobalBaseReg = RegInfo.createVirtualRegister(&MBlaze::GPRRegClass); 00291 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), 00292 GlobalBaseReg).addReg(MBlaze::R20); 00293 RegInfo.addLiveIn(MBlaze::R20); 00294 00295 MBlazeFI->setGlobalBaseReg(GlobalBaseReg); 00296 return GlobalBaseReg; 00297 }