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