LLVM API Documentation
00001 //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===// 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 Alpha implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Alpha.h" 00015 #include "AlphaInstrInfo.h" 00016 #include "AlphaGenInstrInfo.inc" 00017 #include "llvm/ADT/STLExtras.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 using namespace llvm; 00020 00021 AlphaInstrInfo::AlphaInstrInfo() 00022 : TargetInstrInfoImpl(AlphaInsts, array_lengthof(AlphaInsts)), 00023 RI(*this) { } 00024 00025 00026 bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI, 00027 unsigned& sourceReg, 00028 unsigned& destReg) const { 00029 unsigned oc = MI.getOpcode(); 00030 if (oc == Alpha::BISr || 00031 oc == Alpha::CPYSS || 00032 oc == Alpha::CPYST || 00033 oc == Alpha::CPYSSt || 00034 oc == Alpha::CPYSTs) { 00035 // or r1, r2, r2 00036 // cpys(s|t) r1 r2 r2 00037 assert(MI.getNumOperands() >= 3 && 00038 MI.getOperand(0).isReg() && 00039 MI.getOperand(1).isReg() && 00040 MI.getOperand(2).isReg() && 00041 "invalid Alpha BIS instruction!"); 00042 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { 00043 sourceReg = MI.getOperand(1).getReg(); 00044 destReg = MI.getOperand(0).getReg(); 00045 return true; 00046 } 00047 } 00048 return false; 00049 } 00050 00051 unsigned 00052 AlphaInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const { 00053 switch (MI->getOpcode()) { 00054 case Alpha::LDL: 00055 case Alpha::LDQ: 00056 case Alpha::LDBU: 00057 case Alpha::LDWU: 00058 case Alpha::LDS: 00059 case Alpha::LDT: 00060 if (MI->getOperand(1).isFI()) { 00061 FrameIndex = MI->getOperand(1).getIndex(); 00062 return MI->getOperand(0).getReg(); 00063 } 00064 break; 00065 } 00066 return 0; 00067 } 00068 00069 unsigned 00070 AlphaInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { 00071 switch (MI->getOpcode()) { 00072 case Alpha::STL: 00073 case Alpha::STQ: 00074 case Alpha::STB: 00075 case Alpha::STW: 00076 case Alpha::STS: 00077 case Alpha::STT: 00078 if (MI->getOperand(1).isFI()) { 00079 FrameIndex = MI->getOperand(1).getIndex(); 00080 return MI->getOperand(0).getReg(); 00081 } 00082 break; 00083 } 00084 return 0; 00085 } 00086 00087 static bool isAlphaIntCondCode(unsigned Opcode) { 00088 switch (Opcode) { 00089 case Alpha::BEQ: 00090 case Alpha::BNE: 00091 case Alpha::BGE: 00092 case Alpha::BGT: 00093 case Alpha::BLE: 00094 case Alpha::BLT: 00095 case Alpha::BLBC: 00096 case Alpha::BLBS: 00097 return true; 00098 default: 00099 return false; 00100 } 00101 } 00102 00103 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB, 00104 MachineBasicBlock *TBB, 00105 MachineBasicBlock *FBB, 00106 const SmallVectorImpl<MachineOperand> &Cond) const { 00107 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 00108 assert((Cond.size() == 2 || Cond.size() == 0) && 00109 "Alpha branch conditions have two components!"); 00110 00111 // One-way branch. 00112 if (FBB == 0) { 00113 if (Cond.empty()) // Unconditional branch 00114 BuildMI(&MBB, get(Alpha::BR)).addMBB(TBB); 00115 else // Conditional branch 00116 if (isAlphaIntCondCode(Cond[0].getImm())) 00117 BuildMI(&MBB, get(Alpha::COND_BRANCH_I)) 00118 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 00119 else 00120 BuildMI(&MBB, get(Alpha::COND_BRANCH_F)) 00121 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 00122 return 1; 00123 } 00124 00125 // Two-way Conditional Branch. 00126 if (isAlphaIntCondCode(Cond[0].getImm())) 00127 BuildMI(&MBB, get(Alpha::COND_BRANCH_I)) 00128 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 00129 else 00130 BuildMI(&MBB, get(Alpha::COND_BRANCH_F)) 00131 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 00132 BuildMI(&MBB, get(Alpha::BR)).addMBB(FBB); 00133 return 2; 00134 } 00135 00136 bool AlphaInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 00137 MachineBasicBlock::iterator MI, 00138 unsigned DestReg, unsigned SrcReg, 00139 const TargetRegisterClass *DestRC, 00140 const TargetRegisterClass *SrcRC) const { 00141 //cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; 00142 if (DestRC != SrcRC) { 00143 // Not yet supported! 00144 return false; 00145 } 00146 00147 if (DestRC == Alpha::GPRCRegisterClass) { 00148 BuildMI(MBB, MI, get(Alpha::BISr), DestReg).addReg(SrcReg).addReg(SrcReg); 00149 } else if (DestRC == Alpha::F4RCRegisterClass) { 00150 BuildMI(MBB, MI, get(Alpha::CPYSS), DestReg).addReg(SrcReg).addReg(SrcReg); 00151 } else if (DestRC == Alpha::F8RCRegisterClass) { 00152 BuildMI(MBB, MI, get(Alpha::CPYST), DestReg).addReg(SrcReg).addReg(SrcReg); 00153 } else { 00154 // Attempt to copy register that is not GPR or FPR 00155 return false; 00156 } 00157 00158 return true; 00159 } 00160 00161 void 00162 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 00163 MachineBasicBlock::iterator MI, 00164 unsigned SrcReg, bool isKill, int FrameIdx, 00165 const TargetRegisterClass *RC) const { 00166 //cerr << "Trying to store " << getPrettyName(SrcReg) << " to " 00167 // << FrameIdx << "\n"; 00168 //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); 00169 if (RC == Alpha::F4RCRegisterClass) 00170 BuildMI(MBB, MI, get(Alpha::STS)) 00171 .addReg(SrcReg, false, false, isKill) 00172 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00173 else if (RC == Alpha::F8RCRegisterClass) 00174 BuildMI(MBB, MI, get(Alpha::STT)) 00175 .addReg(SrcReg, false, false, isKill) 00176 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00177 else if (RC == Alpha::GPRCRegisterClass) 00178 BuildMI(MBB, MI, get(Alpha::STQ)) 00179 .addReg(SrcReg, false, false, isKill) 00180 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00181 else 00182 abort(); 00183 } 00184 00185 void AlphaInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 00186 bool isKill, 00187 SmallVectorImpl<MachineOperand> &Addr, 00188 const TargetRegisterClass *RC, 00189 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00190 unsigned Opc = 0; 00191 if (RC == Alpha::F4RCRegisterClass) 00192 Opc = Alpha::STS; 00193 else if (RC == Alpha::F8RCRegisterClass) 00194 Opc = Alpha::STT; 00195 else if (RC == Alpha::GPRCRegisterClass) 00196 Opc = Alpha::STQ; 00197 else 00198 abort(); 00199 MachineInstrBuilder MIB = 00200 BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill); 00201 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 00202 MachineOperand &MO = Addr[i]; 00203 if (MO.isReg()) 00204 MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); 00205 else 00206 MIB.addImm(MO.getImm()); 00207 } 00208 NewMIs.push_back(MIB); 00209 } 00210 00211 void 00212 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 00213 MachineBasicBlock::iterator MI, 00214 unsigned DestReg, int FrameIdx, 00215 const TargetRegisterClass *RC) const { 00216 //cerr << "Trying to load " << getPrettyName(DestReg) << " to " 00217 // << FrameIdx << "\n"; 00218 if (RC == Alpha::F4RCRegisterClass) 00219 BuildMI(MBB, MI, get(Alpha::LDS), DestReg) 00220 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00221 else if (RC == Alpha::F8RCRegisterClass) 00222 BuildMI(MBB, MI, get(Alpha::LDT), DestReg) 00223 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00224 else if (RC == Alpha::GPRCRegisterClass) 00225 BuildMI(MBB, MI, get(Alpha::LDQ), DestReg) 00226 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 00227 else 00228 abort(); 00229 } 00230 00231 void AlphaInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 00232 SmallVectorImpl<MachineOperand> &Addr, 00233 const TargetRegisterClass *RC, 00234 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00235 unsigned Opc = 0; 00236 if (RC == Alpha::F4RCRegisterClass) 00237 Opc = Alpha::LDS; 00238 else if (RC == Alpha::F8RCRegisterClass) 00239 Opc = Alpha::LDT; 00240 else if (RC == Alpha::GPRCRegisterClass) 00241 Opc = Alpha::LDQ; 00242 else 00243 abort(); 00244 MachineInstrBuilder MIB = 00245 BuildMI(MF, get(Opc), DestReg); 00246 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 00247 MachineOperand &MO = Addr[i]; 00248 if (MO.isReg()) 00249 MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); 00250 else 00251 MIB.addImm(MO.getImm()); 00252 } 00253 NewMIs.push_back(MIB); 00254 } 00255 00256 MachineInstr *AlphaInstrInfo::foldMemoryOperand(MachineFunction &MF, 00257 MachineInstr *MI, 00258 SmallVectorImpl<unsigned> &Ops, 00259 int FrameIndex) const { 00260 if (Ops.size() != 1) return NULL; 00261 00262 // Make sure this is a reg-reg copy. 00263 unsigned Opc = MI->getOpcode(); 00264 00265 MachineInstr *NewMI = NULL; 00266 switch(Opc) { 00267 default: 00268 break; 00269 case Alpha::BISr: 00270 case Alpha::CPYSS: 00271 case Alpha::CPYST: 00272 if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 00273 if (Ops[0] == 0) { // move -> store 00274 unsigned InReg = MI->getOperand(1).getReg(); 00275 bool isKill = MI->getOperand(1).isKill(); 00276 Opc = (Opc == Alpha::BISr) ? Alpha::STQ : 00277 ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT); 00278 NewMI = BuildMI(MF, get(Opc)).addReg(InReg, false, false, isKill) 00279 .addFrameIndex(FrameIndex) 00280 .addReg(Alpha::F31); 00281 } else { // load -> move 00282 unsigned OutReg = MI->getOperand(0).getReg(); 00283 bool isDead = MI->getOperand(0).isDead(); 00284 Opc = (Opc == Alpha::BISr) ? Alpha::LDQ : 00285 ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT); 00286 NewMI = BuildMI(MF, get(Opc)).addReg(OutReg, true, false, false, isDead) 00287 .addFrameIndex(FrameIndex) 00288 .addReg(Alpha::F31); 00289 } 00290 } 00291 break; 00292 } 00293 return NewMI; 00294 } 00295 00296 static unsigned AlphaRevCondCode(unsigned Opcode) { 00297 switch (Opcode) { 00298 case Alpha::BEQ: return Alpha::BNE; 00299 case Alpha::BNE: return Alpha::BEQ; 00300 case Alpha::BGE: return Alpha::BLT; 00301 case Alpha::BGT: return Alpha::BLE; 00302 case Alpha::BLE: return Alpha::BGT; 00303 case Alpha::BLT: return Alpha::BGE; 00304 case Alpha::BLBC: return Alpha::BLBS; 00305 case Alpha::BLBS: return Alpha::BLBC; 00306 case Alpha::FBEQ: return Alpha::FBNE; 00307 case Alpha::FBNE: return Alpha::FBEQ; 00308 case Alpha::FBGE: return Alpha::FBLT; 00309 case Alpha::FBGT: return Alpha::FBLE; 00310 case Alpha::FBLE: return Alpha::FBGT; 00311 case Alpha::FBLT: return Alpha::FBGE; 00312 default: 00313 assert(0 && "Unknown opcode"); 00314 } 00315 return 0; // Not reached 00316 } 00317 00318 // Branch analysis. 00319 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 00320 MachineBasicBlock *&FBB, 00321 SmallVectorImpl<MachineOperand> &Cond) const { 00322 // If the block has no terminators, it just falls into the block after it. 00323 MachineBasicBlock::iterator I = MBB.end(); 00324 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 00325 return false; 00326 00327 // Get the last instruction in the block. 00328 MachineInstr *LastInst = I; 00329 00330 // If there is only one terminator instruction, process it. 00331 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 00332 if (LastInst->getOpcode() == Alpha::BR) { 00333 TBB = LastInst->getOperand(0).getMBB(); 00334 return false; 00335 } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I || 00336 LastInst->getOpcode() == Alpha::COND_BRANCH_F) { 00337 // Block ends with fall-through condbranch. 00338 TBB = LastInst->getOperand(2).getMBB(); 00339 Cond.push_back(LastInst->getOperand(0)); 00340 Cond.push_back(LastInst->getOperand(1)); 00341 return false; 00342 } 00343 // Otherwise, don't know what this is. 00344 return true; 00345 } 00346 00347 // Get the instruction before it if it's a terminator. 00348 MachineInstr *SecondLastInst = I; 00349 00350 // If there are three terminators, we don't know what sort of block this is. 00351 if (SecondLastInst && I != MBB.begin() && 00352 isUnpredicatedTerminator(--I)) 00353 return true; 00354 00355 // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it. 00356 if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I || 00357 SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) && 00358 LastInst->getOpcode() == Alpha::BR) { 00359 TBB = SecondLastInst->getOperand(2).getMBB(); 00360 Cond.push_back(SecondLastInst->getOperand(0)); 00361 Cond.push_back(SecondLastInst->getOperand(1)); 00362 FBB = LastInst->getOperand(0).getMBB(); 00363 return false; 00364 } 00365 00366 // If the block ends with two Alpha::BRs, handle it. The second one is not 00367 // executed, so remove it. 00368 if (SecondLastInst->getOpcode() == Alpha::BR && 00369 LastInst->getOpcode() == Alpha::BR) { 00370 TBB = SecondLastInst->getOperand(0).getMBB(); 00371 I = LastInst; 00372 I->eraseFromParent(); 00373 return false; 00374 } 00375 00376 // Otherwise, can't handle this. 00377 return true; 00378 } 00379 00380 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 00381 MachineBasicBlock::iterator I = MBB.end(); 00382 if (I == MBB.begin()) return 0; 00383 --I; 00384 if (I->getOpcode() != Alpha::BR && 00385 I->getOpcode() != Alpha::COND_BRANCH_I && 00386 I->getOpcode() != Alpha::COND_BRANCH_F) 00387 return 0; 00388 00389 // Remove the branch. 00390 I->eraseFromParent(); 00391 00392 I = MBB.end(); 00393 00394 if (I == MBB.begin()) return 1; 00395 --I; 00396 if (I->getOpcode() != Alpha::COND_BRANCH_I && 00397 I->getOpcode() != Alpha::COND_BRANCH_F) 00398 return 1; 00399 00400 // Remove the branch. 00401 I->eraseFromParent(); 00402 return 2; 00403 } 00404 00405 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB, 00406 MachineBasicBlock::iterator MI) const { 00407 BuildMI(MBB, MI, get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31) 00408 .addReg(Alpha::R31); 00409 } 00410 00411 bool AlphaInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const { 00412 if (MBB.empty()) return false; 00413 00414 switch (MBB.back().getOpcode()) { 00415 case Alpha::RETDAG: // Return. 00416 case Alpha::RETDAGp: 00417 case Alpha::BR: // Uncond branch. 00418 case Alpha::JMP: // Indirect branch. 00419 return true; 00420 default: return false; 00421 } 00422 } 00423 bool AlphaInstrInfo:: 00424 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 00425 assert(Cond.size() == 2 && "Invalid Alpha branch opcode!"); 00426 Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm())); 00427 return false; 00428 } 00429