1 //===- SystemZInstrInfo.cpp - SystemZ 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 SystemZ implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "SystemZ.h" 15 #include "SystemZInstrBuilder.h" 16 #include "SystemZInstrInfo.h" 17 #include "SystemZMachineFunctionInfo.h" 18 #include "SystemZTargetMachine.h" 19 #include "SystemZGenInstrInfo.inc" 20 #include "llvm/Function.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/PseudoSourceValue.h" 25 #include "llvm/Support/ErrorHandling.h" 26 using namespace llvm; 27 28 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 29 : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)), 30 RI(tm, *this), TM(tm) { 31 } 32 33 /// isGVStub - Return true if the GV requires an extra load to get the 34 /// real address. 35 static inline bool isGVStub(GlobalValue *GV, SystemZTargetMachine &TM) { 36 return TM.getSubtarget<SystemZSubtarget>().GVRequiresExtraLoad(GV, TM, false); 37 } 38 39 void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 40 MachineBasicBlock::iterator MI, 41 unsigned SrcReg, bool isKill, int FrameIdx, 42 const TargetRegisterClass *RC, 43 const TargetRegisterInfo *TRI) const { 44 DebugLoc DL; 45 if (MI != MBB.end()) DL = MI->getDebugLoc(); 46 47 unsigned Opc = 0; 48 if (RC == &SystemZ::GR32RegClass || 49 RC == &SystemZ::ADDR32RegClass) 50 Opc = SystemZ::MOV32mr; 51 else if (RC == &SystemZ::GR64RegClass || 52 RC == &SystemZ::ADDR64RegClass) { 53 Opc = SystemZ::MOV64mr; 54 } else if (RC == &SystemZ::FP32RegClass) { 55 Opc = SystemZ::FMOV32mr; 56 } else if (RC == &SystemZ::FP64RegClass) { 57 Opc = SystemZ::FMOV64mr; 58 } else if (RC == &SystemZ::GR64PRegClass) { 59 Opc = SystemZ::MOV64Pmr; 60 } else if (RC == &SystemZ::GR128RegClass) { 61 Opc = SystemZ::MOV128mr; 62 } else 63 llvm_unreachable("Unsupported regclass to store"); 64 65 addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx) 66 .addReg(SrcReg, getKillRegState(isKill)); 67 } 68 69 void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 70 MachineBasicBlock::iterator MI, 71 unsigned DestReg, int FrameIdx, 72 const TargetRegisterClass *RC, 73 const TargetRegisterInfo *TRI) const{ 74 DebugLoc DL; 75 if (MI != MBB.end()) DL = MI->getDebugLoc(); 76 77 unsigned Opc = 0; 78 if (RC == &SystemZ::GR32RegClass || 79 RC == &SystemZ::ADDR32RegClass) 80 Opc = SystemZ::MOV32rm; 81 else if (RC == &SystemZ::GR64RegClass || 82 RC == &SystemZ::ADDR64RegClass) { 83 Opc = SystemZ::MOV64rm; 84 } else if (RC == &SystemZ::FP32RegClass) { 85 Opc = SystemZ::FMOV32rm; 86 } else if (RC == &SystemZ::FP64RegClass) { 87 Opc = SystemZ::FMOV64rm; 88 } else if (RC == &SystemZ::GR64PRegClass) { 89 Opc = SystemZ::MOV64Prm; 90 } else if (RC == &SystemZ::GR128RegClass) { 91 Opc = SystemZ::MOV128rm; 92 } else 93 llvm_unreachable("Unsupported regclass to load"); 94 95 addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx); 96 } 97 98 void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 99 MachineBasicBlock::iterator I, DebugLoc DL, 100 unsigned DestReg, unsigned SrcReg, 101 bool KillSrc) const { 102 unsigned Opc; 103 if (SystemZ::GR64RegClass.contains(DestReg, SrcReg)) 104 Opc = SystemZ::MOV64rr; 105 else if (SystemZ::GR32RegClass.contains(DestReg, SrcReg)) 106 Opc = SystemZ::MOV32rr; 107 else if (SystemZ::GR64PRegClass.contains(DestReg, SrcReg)) 108 Opc = SystemZ::MOV64rrP; 109 else if (SystemZ::GR128RegClass.contains(DestReg, SrcReg)) 110 Opc = SystemZ::MOV128rr; 111 else if (SystemZ::FP32RegClass.contains(DestReg, SrcReg)) 112 Opc = SystemZ::FMOV32rr; 113 else if (SystemZ::FP64RegClass.contains(DestReg, SrcReg)) 114 Opc = SystemZ::FMOV64rr; 115 else 116 llvm_unreachable("Impossible reg-to-reg copy"); 117 118 BuildMI(MBB, I, DL, get(Opc), DestReg) 119 .addReg(SrcReg, getKillRegState(KillSrc)); 120 } 121 122 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 123 int &FrameIndex) const { 124 switch (MI->getOpcode()) { 125 default: break; 126 case SystemZ::MOV32rm: 127 case SystemZ::MOV32rmy: 128 case SystemZ::MOV64rm: 129 case SystemZ::MOVSX32rm8: 130 case SystemZ::MOVSX32rm16y: 131 case SystemZ::MOVSX64rm8: 132 case SystemZ::MOVSX64rm16: 133 case SystemZ::MOVSX64rm32: 134 case SystemZ::MOVZX32rm8: 135 case SystemZ::MOVZX32rm16: 136 case SystemZ::MOVZX64rm8: 137 case SystemZ::MOVZX64rm16: 138 case SystemZ::MOVZX64rm32: 139 case SystemZ::FMOV32rm: 140 case SystemZ::FMOV32rmy: 141 case SystemZ::FMOV64rm: 142 case SystemZ::FMOV64rmy: 143 case SystemZ::MOV64Prm: 144 case SystemZ::MOV64Prmy: 145 case SystemZ::MOV128rm: 146 if (MI->getOperand(1).isFI() && 147 MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && 148 MI->getOperand(2).getImm() == 0 && MI->getOperand(3).getReg() == 0) { 149 FrameIndex = MI->getOperand(1).getIndex(); 150 return MI->getOperand(0).getReg(); 151 } 152 break; 153 } 154 return 0; 155 } 156 157 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 158 int &FrameIndex) const { 159 switch (MI->getOpcode()) { 160 default: break; 161 case SystemZ::MOV32mr: 162 case SystemZ::MOV32mry: 163 case SystemZ::MOV64mr: 164 case SystemZ::MOV32m8r: 165 case SystemZ::MOV32m8ry: 166 case SystemZ::MOV32m16r: 167 case SystemZ::MOV32m16ry: 168 case SystemZ::MOV64m8r: 169 case SystemZ::MOV64m8ry: 170 case SystemZ::MOV64m16r: 171 case SystemZ::MOV64m16ry: 172 case SystemZ::MOV64m32r: 173 case SystemZ::MOV64m32ry: 174 case SystemZ::FMOV32mr: 175 case SystemZ::FMOV32mry: 176 case SystemZ::FMOV64mr: 177 case SystemZ::FMOV64mry: 178 case SystemZ::MOV64Pmr: 179 case SystemZ::MOV64Pmry: 180 case SystemZ::MOV128mr: 181 if (MI->getOperand(0).isFI() && 182 MI->getOperand(1).isImm() && MI->getOperand(2).isReg() && 183 MI->getOperand(1).getImm() == 0 && MI->getOperand(2).getReg() == 0) { 184 FrameIndex = MI->getOperand(0).getIndex(); 185 return MI->getOperand(3).getReg(); 186 } 187 break; 188 } 189 return 0; 190 } 191 192 bool SystemZInstrInfo:: 193 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 194 assert(Cond.size() == 1 && "Invalid Xbranch condition!"); 195 196 SystemZCC::CondCodes CC = static_cast<SystemZCC::CondCodes>(Cond[0].getImm()); 197 Cond[0].setImm(getOppositeCondition(CC)); 198 return false; 199 } 200 201 bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { 202 const TargetInstrDesc &TID = MI->getDesc(); 203 if (!TID.isTerminator()) return false; 204 205 // Conditional branch is a special case. 206 if (TID.isBranch() && !TID.isBarrier()) 207 return true; 208 if (!TID.isPredicable()) 209 return true; 210 return !isPredicated(MI); 211 } 212 213 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 214 MachineBasicBlock *&TBB, 215 MachineBasicBlock *&FBB, 216 SmallVectorImpl<MachineOperand> &Cond, 217 bool AllowModify) const { 218 // Start from the bottom of the block and work up, examining the 219 // terminator instructions. 220 MachineBasicBlock::iterator I = MBB.end(); 221 while (I != MBB.begin()) { 222 --I; 223 if (I->isDebugValue()) 224 continue; 225 // Working from the bottom, when we see a non-terminator 226 // instruction, we're done. 227 if (!isUnpredicatedTerminator(I)) 228 break; 229 230 // A terminator that isn't a branch can't easily be handled 231 // by this analysis. 232 if (!I->getDesc().isBranch()) 233 return true; 234 235 // Handle unconditional branches. 236 if (I->getOpcode() == SystemZ::JMP) { 237 if (!AllowModify) { 238 TBB = I->getOperand(0).getMBB(); 239 continue; 240 } 241 242 // If the block has any instructions after a JMP, delete them. 243 while (llvm::next(I) != MBB.end()) 244 llvm::next(I)->eraseFromParent(); 245 Cond.clear(); 246 FBB = 0; 247 248 // Delete the JMP if it's equivalent to a fall-through. 249 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 250 TBB = 0; 251 I->eraseFromParent(); 252 I = MBB.end(); 253 continue; 254 } 255 256 // TBB is used to indicate the unconditinal destination. 257 TBB = I->getOperand(0).getMBB(); 258 continue; 259 } 260 261 // Handle conditional branches. 262 SystemZCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode()); 263 if (BranchCode == SystemZCC::INVALID) 264 return true; // Can't handle indirect branch. 265 266 // Working from the bottom, handle the first conditional branch. 267 if (Cond.empty()) { 268 FBB = TBB; 269 TBB = I->getOperand(0).getMBB(); 270 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 271 continue; 272 } 273 274 // Handle subsequent conditional branches. Only handle the case where all 275 // conditional branches branch to the same destination. 276 assert(Cond.size() == 1); 277 assert(TBB); 278 279 // Only handle the case where all conditional branches branch to 280 // the same destination. 281 if (TBB != I->getOperand(0).getMBB()) 282 return true; 283 284 SystemZCC::CondCodes OldBranchCode = (SystemZCC::CondCodes)Cond[0].getImm(); 285 // If the conditions are the same, we can leave them alone. 286 if (OldBranchCode == BranchCode) 287 continue; 288 289 return true; 290 } 291 292 return false; 293 } 294 295 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 296 MachineBasicBlock::iterator I = MBB.end(); 297 unsigned Count = 0; 298 299 while (I != MBB.begin()) { 300 --I; 301 if (I->isDebugValue()) 302 continue; 303 if (I->getOpcode() != SystemZ::JMP && 304 getCondFromBranchOpc(I->getOpcode()) == SystemZCC::INVALID) 305 break; 306 // Remove the branch. 307 I->eraseFromParent(); 308 I = MBB.end(); 309 ++Count; 310 } 311 312 return Count; 313 } 314 315 unsigned 316 SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 317 MachineBasicBlock *FBB, 318 const SmallVectorImpl<MachineOperand> &Cond, 319 DebugLoc DL) const { 320 // Shouldn't be a fall through. 321 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 322 assert((Cond.size() == 1 || Cond.size() == 0) && 323 "SystemZ branch conditions have one component!"); 324 325 if (Cond.empty()) { 326 // Unconditional branch? 327 assert(!FBB && "Unconditional branch with multiple successors!"); 328 BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(TBB); 329 return 1; 330 } 331 332 // Conditional branch. 333 unsigned Count = 0; 334 SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm(); 335 BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB); 336 ++Count; 337 338 if (FBB) { 339 // Two-way Conditional branch. Insert the second branch. 340 BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(FBB); 341 ++Count; 342 } 343 return Count; 344 } 345 346 const TargetInstrDesc& 347 SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const { 348 switch (CC) { 349 default: 350 llvm_unreachable("Unknown condition code!"); 351 case SystemZCC::O: return get(SystemZ::JO); 352 case SystemZCC::H: return get(SystemZ::JH); 353 case SystemZCC::NLE: return get(SystemZ::JNLE); 354 case SystemZCC::L: return get(SystemZ::JL); 355 case SystemZCC::NHE: return get(SystemZ::JNHE); 356 case SystemZCC::LH: return get(SystemZ::JLH); 357 case SystemZCC::NE: return get(SystemZ::JNE); 358 case SystemZCC::E: return get(SystemZ::JE); 359 case SystemZCC::NLH: return get(SystemZ::JNLH); 360 case SystemZCC::HE: return get(SystemZ::JHE); 361 case SystemZCC::NL: return get(SystemZ::JNL); 362 case SystemZCC::LE: return get(SystemZ::JLE); 363 case SystemZCC::NH: return get(SystemZ::JNH); 364 case SystemZCC::NO: return get(SystemZ::JNO); 365 } 366 } 367 368 SystemZCC::CondCodes 369 SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc) const { 370 switch (Opc) { 371 default: return SystemZCC::INVALID; 372 case SystemZ::JO: return SystemZCC::O; 373 case SystemZ::JH: return SystemZCC::H; 374 case SystemZ::JNLE: return SystemZCC::NLE; 375 case SystemZ::JL: return SystemZCC::L; 376 case SystemZ::JNHE: return SystemZCC::NHE; 377 case SystemZ::JLH: return SystemZCC::LH; 378 case SystemZ::JNE: return SystemZCC::NE; 379 case SystemZ::JE: return SystemZCC::E; 380 case SystemZ::JNLH: return SystemZCC::NLH; 381 case SystemZ::JHE: return SystemZCC::HE; 382 case SystemZ::JNL: return SystemZCC::NL; 383 case SystemZ::JLE: return SystemZCC::LE; 384 case SystemZ::JNH: return SystemZCC::NH; 385 case SystemZ::JNO: return SystemZCC::NO; 386 } 387 } 388 389 SystemZCC::CondCodes 390 SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC) const { 391 switch (CC) { 392 default: 393 llvm_unreachable("Invalid condition!"); 394 case SystemZCC::O: return SystemZCC::NO; 395 case SystemZCC::H: return SystemZCC::NH; 396 case SystemZCC::NLE: return SystemZCC::LE; 397 case SystemZCC::L: return SystemZCC::NL; 398 case SystemZCC::NHE: return SystemZCC::HE; 399 case SystemZCC::LH: return SystemZCC::NLH; 400 case SystemZCC::NE: return SystemZCC::E; 401 case SystemZCC::E: return SystemZCC::NE; 402 case SystemZCC::NLH: return SystemZCC::LH; 403 case SystemZCC::HE: return SystemZCC::NHE; 404 case SystemZCC::NL: return SystemZCC::L; 405 case SystemZCC::LE: return SystemZCC::NLE; 406 case SystemZCC::NH: return SystemZCC::H; 407 case SystemZCC::NO: return SystemZCC::O; 408 } 409 } 410 411 const TargetInstrDesc& 412 SystemZInstrInfo::getLongDispOpc(unsigned Opc) const { 413 switch (Opc) { 414 default: 415 llvm_unreachable("Don't have long disp version of this instruction"); 416 case SystemZ::MOV32mr: return get(SystemZ::MOV32mry); 417 case SystemZ::MOV32rm: return get(SystemZ::MOV32rmy); 418 case SystemZ::MOVSX32rm16: return get(SystemZ::MOVSX32rm16y); 419 case SystemZ::MOV32m8r: return get(SystemZ::MOV32m8ry); 420 case SystemZ::MOV32m16r: return get(SystemZ::MOV32m16ry); 421 case SystemZ::MOV64m8r: return get(SystemZ::MOV64m8ry); 422 case SystemZ::MOV64m16r: return get(SystemZ::MOV64m16ry); 423 case SystemZ::MOV64m32r: return get(SystemZ::MOV64m32ry); 424 case SystemZ::MOV8mi: return get(SystemZ::MOV8miy); 425 case SystemZ::MUL32rm: return get(SystemZ::MUL32rmy); 426 case SystemZ::CMP32rm: return get(SystemZ::CMP32rmy); 427 case SystemZ::UCMP32rm: return get(SystemZ::UCMP32rmy); 428 case SystemZ::FMOV32mr: return get(SystemZ::FMOV32mry); 429 case SystemZ::FMOV64mr: return get(SystemZ::FMOV64mry); 430 case SystemZ::FMOV32rm: return get(SystemZ::FMOV32rmy); 431 case SystemZ::FMOV64rm: return get(SystemZ::FMOV64rmy); 432 case SystemZ::MOV64Pmr: return get(SystemZ::MOV64Pmry); 433 case SystemZ::MOV64Prm: return get(SystemZ::MOV64Prmy); 434 } 435 } 436