1 //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===// 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 Alpha implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Alpha.h" 15 #include "AlphaInstrInfo.h" 16 #include "AlphaMachineFunctionInfo.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/Support/ErrorHandling.h" 22 23 #define GET_INSTRINFO_CTOR 24 #include "AlphaGenInstrInfo.inc" 25 using namespace llvm; 26 27 AlphaInstrInfo::AlphaInstrInfo() 28 : AlphaGenInstrInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP), 29 RI(*this) { 30 } 31 32 33 unsigned 34 AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 35 int &FrameIndex) const { 36 switch (MI->getOpcode()) { 37 case Alpha::LDL: 38 case Alpha::LDQ: 39 case Alpha::LDBU: 40 case Alpha::LDWU: 41 case Alpha::LDS: 42 case Alpha::LDT: 43 if (MI->getOperand(1).isFI()) { 44 FrameIndex = MI->getOperand(1).getIndex(); 45 return MI->getOperand(0).getReg(); 46 } 47 break; 48 } 49 return 0; 50 } 51 52 unsigned 53 AlphaInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 54 int &FrameIndex) const { 55 switch (MI->getOpcode()) { 56 case Alpha::STL: 57 case Alpha::STQ: 58 case Alpha::STB: 59 case Alpha::STW: 60 case Alpha::STS: 61 case Alpha::STT: 62 if (MI->getOperand(1).isFI()) { 63 FrameIndex = MI->getOperand(1).getIndex(); 64 return MI->getOperand(0).getReg(); 65 } 66 break; 67 } 68 return 0; 69 } 70 71 static bool isAlphaIntCondCode(unsigned Opcode) { 72 switch (Opcode) { 73 case Alpha::BEQ: 74 case Alpha::BNE: 75 case Alpha::BGE: 76 case Alpha::BGT: 77 case Alpha::BLE: 78 case Alpha::BLT: 79 case Alpha::BLBC: 80 case Alpha::BLBS: 81 return true; 82 default: 83 return false; 84 } 85 } 86 87 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB, 88 MachineBasicBlock *TBB, 89 MachineBasicBlock *FBB, 90 const SmallVectorImpl<MachineOperand> &Cond, 91 DebugLoc DL) const { 92 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 93 assert((Cond.size() == 2 || Cond.size() == 0) && 94 "Alpha branch conditions have two components!"); 95 96 // One-way branch. 97 if (FBB == 0) { 98 if (Cond.empty()) // Unconditional branch 99 BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(TBB); 100 else // Conditional branch 101 if (isAlphaIntCondCode(Cond[0].getImm())) 102 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I)) 103 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 104 else 105 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F)) 106 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 107 return 1; 108 } 109 110 // Two-way Conditional Branch. 111 if (isAlphaIntCondCode(Cond[0].getImm())) 112 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I)) 113 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 114 else 115 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F)) 116 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 117 BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(FBB); 118 return 2; 119 } 120 121 void AlphaInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 122 MachineBasicBlock::iterator MI, DebugLoc DL, 123 unsigned DestReg, unsigned SrcReg, 124 bool KillSrc) const { 125 if (Alpha::GPRCRegClass.contains(DestReg, SrcReg)) { 126 BuildMI(MBB, MI, DL, get(Alpha::BISr), DestReg) 127 .addReg(SrcReg) 128 .addReg(SrcReg, getKillRegState(KillSrc)); 129 } else if (Alpha::F4RCRegClass.contains(DestReg, SrcReg)) { 130 BuildMI(MBB, MI, DL, get(Alpha::CPYSS), DestReg) 131 .addReg(SrcReg) 132 .addReg(SrcReg, getKillRegState(KillSrc)); 133 } else if (Alpha::F8RCRegClass.contains(DestReg, SrcReg)) { 134 BuildMI(MBB, MI, DL, get(Alpha::CPYST), DestReg) 135 .addReg(SrcReg) 136 .addReg(SrcReg, getKillRegState(KillSrc)); 137 } else { 138 llvm_unreachable("Attempt to copy register that is not GPR or FPR"); 139 } 140 } 141 142 void 143 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 144 MachineBasicBlock::iterator MI, 145 unsigned SrcReg, bool isKill, int FrameIdx, 146 const TargetRegisterClass *RC, 147 const TargetRegisterInfo *TRI) const { 148 //cerr << "Trying to store " << getPrettyName(SrcReg) << " to " 149 // << FrameIdx << "\n"; 150 //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); 151 152 DebugLoc DL; 153 if (MI != MBB.end()) DL = MI->getDebugLoc(); 154 155 if (RC == Alpha::F4RCRegisterClass) 156 BuildMI(MBB, MI, DL, get(Alpha::STS)) 157 .addReg(SrcReg, getKillRegState(isKill)) 158 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 159 else if (RC == Alpha::F8RCRegisterClass) 160 BuildMI(MBB, MI, DL, get(Alpha::STT)) 161 .addReg(SrcReg, getKillRegState(isKill)) 162 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 163 else if (RC == Alpha::GPRCRegisterClass) 164 BuildMI(MBB, MI, DL, get(Alpha::STQ)) 165 .addReg(SrcReg, getKillRegState(isKill)) 166 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 167 else 168 llvm_unreachable("Unhandled register class"); 169 } 170 171 void 172 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 173 MachineBasicBlock::iterator MI, 174 unsigned DestReg, int FrameIdx, 175 const TargetRegisterClass *RC, 176 const TargetRegisterInfo *TRI) const { 177 //cerr << "Trying to load " << getPrettyName(DestReg) << " to " 178 // << FrameIdx << "\n"; 179 DebugLoc DL; 180 if (MI != MBB.end()) DL = MI->getDebugLoc(); 181 182 if (RC == Alpha::F4RCRegisterClass) 183 BuildMI(MBB, MI, DL, get(Alpha::LDS), DestReg) 184 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 185 else if (RC == Alpha::F8RCRegisterClass) 186 BuildMI(MBB, MI, DL, get(Alpha::LDT), DestReg) 187 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 188 else if (RC == Alpha::GPRCRegisterClass) 189 BuildMI(MBB, MI, DL, get(Alpha::LDQ), DestReg) 190 .addFrameIndex(FrameIdx).addReg(Alpha::F31); 191 else 192 llvm_unreachable("Unhandled register class"); 193 } 194 195 static unsigned AlphaRevCondCode(unsigned Opcode) { 196 switch (Opcode) { 197 case Alpha::BEQ: return Alpha::BNE; 198 case Alpha::BNE: return Alpha::BEQ; 199 case Alpha::BGE: return Alpha::BLT; 200 case Alpha::BGT: return Alpha::BLE; 201 case Alpha::BLE: return Alpha::BGT; 202 case Alpha::BLT: return Alpha::BGE; 203 case Alpha::BLBC: return Alpha::BLBS; 204 case Alpha::BLBS: return Alpha::BLBC; 205 case Alpha::FBEQ: return Alpha::FBNE; 206 case Alpha::FBNE: return Alpha::FBEQ; 207 case Alpha::FBGE: return Alpha::FBLT; 208 case Alpha::FBGT: return Alpha::FBLE; 209 case Alpha::FBLE: return Alpha::FBGT; 210 case Alpha::FBLT: return Alpha::FBGE; 211 default: 212 llvm_unreachable("Unknown opcode"); 213 } 214 return 0; // Not reached 215 } 216 217 // Branch analysis. 218 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 219 MachineBasicBlock *&FBB, 220 SmallVectorImpl<MachineOperand> &Cond, 221 bool AllowModify) const { 222 // If the block has no terminators, it just falls into the block after it. 223 MachineBasicBlock::iterator I = MBB.end(); 224 if (I == MBB.begin()) 225 return false; 226 --I; 227 while (I->isDebugValue()) { 228 if (I == MBB.begin()) 229 return false; 230 --I; 231 } 232 if (!isUnpredicatedTerminator(I)) 233 return false; 234 235 // Get the last instruction in the block. 236 MachineInstr *LastInst = I; 237 238 // If there is only one terminator instruction, process it. 239 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 240 if (LastInst->getOpcode() == Alpha::BR) { 241 TBB = LastInst->getOperand(0).getMBB(); 242 return false; 243 } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I || 244 LastInst->getOpcode() == Alpha::COND_BRANCH_F) { 245 // Block ends with fall-through condbranch. 246 TBB = LastInst->getOperand(2).getMBB(); 247 Cond.push_back(LastInst->getOperand(0)); 248 Cond.push_back(LastInst->getOperand(1)); 249 return false; 250 } 251 // Otherwise, don't know what this is. 252 return true; 253 } 254 255 // Get the instruction before it if it's a terminator. 256 MachineInstr *SecondLastInst = I; 257 258 // If there are three terminators, we don't know what sort of block this is. 259 if (SecondLastInst && I != MBB.begin() && 260 isUnpredicatedTerminator(--I)) 261 return true; 262 263 // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it. 264 if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I || 265 SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) && 266 LastInst->getOpcode() == Alpha::BR) { 267 TBB = SecondLastInst->getOperand(2).getMBB(); 268 Cond.push_back(SecondLastInst->getOperand(0)); 269 Cond.push_back(SecondLastInst->getOperand(1)); 270 FBB = LastInst->getOperand(0).getMBB(); 271 return false; 272 } 273 274 // If the block ends with two Alpha::BRs, handle it. The second one is not 275 // executed, so remove it. 276 if (SecondLastInst->getOpcode() == Alpha::BR && 277 LastInst->getOpcode() == Alpha::BR) { 278 TBB = SecondLastInst->getOperand(0).getMBB(); 279 I = LastInst; 280 if (AllowModify) 281 I->eraseFromParent(); 282 return false; 283 } 284 285 // Otherwise, can't handle this. 286 return true; 287 } 288 289 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 290 MachineBasicBlock::iterator I = MBB.end(); 291 if (I == MBB.begin()) return 0; 292 --I; 293 while (I->isDebugValue()) { 294 if (I == MBB.begin()) 295 return 0; 296 --I; 297 } 298 if (I->getOpcode() != Alpha::BR && 299 I->getOpcode() != Alpha::COND_BRANCH_I && 300 I->getOpcode() != Alpha::COND_BRANCH_F) 301 return 0; 302 303 // Remove the branch. 304 I->eraseFromParent(); 305 306 I = MBB.end(); 307 308 if (I == MBB.begin()) return 1; 309 --I; 310 if (I->getOpcode() != Alpha::COND_BRANCH_I && 311 I->getOpcode() != Alpha::COND_BRANCH_F) 312 return 1; 313 314 // Remove the branch. 315 I->eraseFromParent(); 316 return 2; 317 } 318 319 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB, 320 MachineBasicBlock::iterator MI) const { 321 DebugLoc DL; 322 BuildMI(MBB, MI, DL, get(Alpha::BISr), Alpha::R31) 323 .addReg(Alpha::R31) 324 .addReg(Alpha::R31); 325 } 326 327 bool AlphaInstrInfo:: 328 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 329 assert(Cond.size() == 2 && "Invalid Alpha branch opcode!"); 330 Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm())); 331 return false; 332 } 333 334 /// getGlobalBaseReg - Return a virtual register initialized with the 335 /// the global base register value. Output instructions required to 336 /// initialize the register in the function entry block, if necessary. 337 /// 338 unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 339 AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>(); 340 unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg(); 341 if (GlobalBaseReg != 0) 342 return GlobalBaseReg; 343 344 // Insert the set of GlobalBaseReg into the first MBB of the function 345 MachineBasicBlock &FirstMBB = MF->front(); 346 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 347 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 348 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 349 350 GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass); 351 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), 352 GlobalBaseReg).addReg(Alpha::R29); 353 RegInfo.addLiveIn(Alpha::R29); 354 355 AlphaFI->setGlobalBaseReg(GlobalBaseReg); 356 return GlobalBaseReg; 357 } 358 359 /// getGlobalRetAddr - Return a virtual register initialized with the 360 /// the global base register value. Output instructions required to 361 /// initialize the register in the function entry block, if necessary. 362 /// 363 unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const { 364 AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>(); 365 unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr(); 366 if (GlobalRetAddr != 0) 367 return GlobalRetAddr; 368 369 // Insert the set of GlobalRetAddr into the first MBB of the function 370 MachineBasicBlock &FirstMBB = MF->front(); 371 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 372 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 373 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 374 375 GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass); 376 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), 377 GlobalRetAddr).addReg(Alpha::R26); 378 RegInfo.addLiveIn(Alpha::R26); 379 380 AlphaFI->setGlobalRetAddr(GlobalRetAddr); 381 return GlobalRetAddr; 382 } 383