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