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 "SystemZInstrInfo.h" 15 #include "SystemZInstrBuilder.h" 16 #include "llvm/Target/TargetMachine.h" 17 18 #define GET_INSTRINFO_CTOR 19 #define GET_INSTRMAP_INFO 20 #include "SystemZGenInstrInfo.inc" 21 22 using namespace llvm; 23 24 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 25 : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 26 RI(tm) { 27 } 28 29 // MI is a 128-bit load or store. Split it into two 64-bit loads or stores, 30 // each having the opcode given by NewOpcode. 31 void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, 32 unsigned NewOpcode) const { 33 MachineBasicBlock *MBB = MI->getParent(); 34 MachineFunction &MF = *MBB->getParent(); 35 36 // Get two load or store instructions. Use the original instruction for one 37 // of them (arbitarily the second here) and create a clone for the other. 38 MachineInstr *EarlierMI = MF.CloneMachineInstr(MI); 39 MBB->insert(MI, EarlierMI); 40 41 // Set up the two 64-bit registers. 42 MachineOperand &HighRegOp = EarlierMI->getOperand(0); 43 MachineOperand &LowRegOp = MI->getOperand(0); 44 HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high)); 45 LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low)); 46 47 // The address in the first (high) instruction is already correct. 48 // Adjust the offset in the second (low) instruction. 49 MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); 50 MachineOperand &LowOffsetOp = MI->getOperand(2); 51 LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); 52 53 // Set the opcodes. 54 unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); 55 unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); 56 assert(HighOpcode && LowOpcode && "Both offsets should be in range"); 57 58 EarlierMI->setDesc(get(HighOpcode)); 59 MI->setDesc(get(LowOpcode)); 60 } 61 62 // Split ADJDYNALLOC instruction MI. 63 void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { 64 MachineBasicBlock *MBB = MI->getParent(); 65 MachineFunction &MF = *MBB->getParent(); 66 MachineFrameInfo *MFFrame = MF.getFrameInfo(); 67 MachineOperand &OffsetMO = MI->getOperand(2); 68 69 uint64_t Offset = (MFFrame->getMaxCallFrameSize() + 70 SystemZMC::CallFrameSize + 71 OffsetMO.getImm()); 72 unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); 73 assert(NewOpcode && "No support for huge argument lists yet"); 74 MI->setDesc(get(NewOpcode)); 75 OffsetMO.setImm(Offset); 76 } 77 78 // If MI is a simple load or store for a frame object, return the register 79 // it loads or stores and set FrameIndex to the index of the frame object. 80 // Return 0 otherwise. 81 // 82 // Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 83 static int isSimpleMove(const MachineInstr *MI, int &FrameIndex, int Flag) { 84 const MCInstrDesc &MCID = MI->getDesc(); 85 if ((MCID.TSFlags & Flag) && 86 MI->getOperand(1).isFI() && 87 MI->getOperand(2).getImm() == 0 && 88 MI->getOperand(3).getReg() == 0) { 89 FrameIndex = MI->getOperand(1).getIndex(); 90 return MI->getOperand(0).getReg(); 91 } 92 return 0; 93 } 94 95 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 96 int &FrameIndex) const { 97 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 98 } 99 100 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 101 int &FrameIndex) const { 102 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 103 } 104 105 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 106 MachineBasicBlock *&TBB, 107 MachineBasicBlock *&FBB, 108 SmallVectorImpl<MachineOperand> &Cond, 109 bool AllowModify) const { 110 // Most of the code and comments here are boilerplate. 111 112 // Start from the bottom of the block and work up, examining the 113 // terminator instructions. 114 MachineBasicBlock::iterator I = MBB.end(); 115 while (I != MBB.begin()) { 116 --I; 117 if (I->isDebugValue()) 118 continue; 119 120 // Working from the bottom, when we see a non-terminator instruction, we're 121 // done. 122 if (!isUnpredicatedTerminator(I)) 123 break; 124 125 // A terminator that isn't a branch can't easily be handled by this 126 // analysis. 127 if (!I->isBranch()) 128 return true; 129 130 // Can't handle indirect branches. 131 SystemZII::Branch Branch(getBranchInfo(I)); 132 if (!Branch.Target->isMBB()) 133 return true; 134 135 // Punt on compound branches. 136 if (Branch.Type != SystemZII::BranchNormal) 137 return true; 138 139 if (Branch.CCMask == SystemZ::CCMASK_ANY) { 140 // Handle unconditional branches. 141 if (!AllowModify) { 142 TBB = Branch.Target->getMBB(); 143 continue; 144 } 145 146 // If the block has any instructions after a JMP, delete them. 147 while (llvm::next(I) != MBB.end()) 148 llvm::next(I)->eraseFromParent(); 149 150 Cond.clear(); 151 FBB = 0; 152 153 // Delete the JMP if it's equivalent to a fall-through. 154 if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { 155 TBB = 0; 156 I->eraseFromParent(); 157 I = MBB.end(); 158 continue; 159 } 160 161 // TBB is used to indicate the unconditinal destination. 162 TBB = Branch.Target->getMBB(); 163 continue; 164 } 165 166 // Working from the bottom, handle the first conditional branch. 167 if (Cond.empty()) { 168 // FIXME: add X86-style branch swap 169 FBB = TBB; 170 TBB = Branch.Target->getMBB(); 171 Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); 172 continue; 173 } 174 175 // Handle subsequent conditional branches. 176 assert(Cond.size() == 1); 177 assert(TBB); 178 179 // Only handle the case where all conditional branches branch to the same 180 // destination. 181 if (TBB != Branch.Target->getMBB()) 182 return true; 183 184 // If the conditions are the same, we can leave them alone. 185 unsigned OldCond = Cond[0].getImm(); 186 if (OldCond == Branch.CCMask) 187 continue; 188 189 // FIXME: Try combining conditions like X86 does. Should be easy on Z! 190 } 191 192 return false; 193 } 194 195 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 196 // Most of the code and comments here are boilerplate. 197 MachineBasicBlock::iterator I = MBB.end(); 198 unsigned Count = 0; 199 200 while (I != MBB.begin()) { 201 --I; 202 if (I->isDebugValue()) 203 continue; 204 if (!I->isBranch()) 205 break; 206 if (!getBranchInfo(I).Target->isMBB()) 207 break; 208 // Remove the branch. 209 I->eraseFromParent(); 210 I = MBB.end(); 211 ++Count; 212 } 213 214 return Count; 215 } 216 217 unsigned 218 SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 219 MachineBasicBlock *FBB, 220 const SmallVectorImpl<MachineOperand> &Cond, 221 DebugLoc DL) const { 222 // In this function we output 32-bit branches, which should always 223 // have enough range. They can be shortened and relaxed by later code 224 // in the pipeline, if desired. 225 226 // Shouldn't be a fall through. 227 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 228 assert((Cond.size() == 1 || Cond.size() == 0) && 229 "SystemZ branch conditions have one component!"); 230 231 if (Cond.empty()) { 232 // Unconditional branch? 233 assert(!FBB && "Unconditional branch with multiple successors!"); 234 BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); 235 return 1; 236 } 237 238 // Conditional branch. 239 unsigned Count = 0; 240 unsigned CC = Cond[0].getImm(); 241 BuildMI(&MBB, DL, get(SystemZ::BRC)).addImm(CC).addMBB(TBB); 242 ++Count; 243 244 if (FBB) { 245 // Two-way Conditional branch. Insert the second branch. 246 BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); 247 ++Count; 248 } 249 return Count; 250 } 251 252 void 253 SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 254 MachineBasicBlock::iterator MBBI, DebugLoc DL, 255 unsigned DestReg, unsigned SrcReg, 256 bool KillSrc) const { 257 // Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too. 258 if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) { 259 copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high), 260 RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc); 261 copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low), 262 RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc); 263 return; 264 } 265 266 // Everything else needs only one instruction. 267 unsigned Opcode; 268 if (SystemZ::GR32BitRegClass.contains(DestReg, SrcReg)) 269 Opcode = SystemZ::LR; 270 else if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) 271 Opcode = SystemZ::LGR; 272 else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)) 273 Opcode = SystemZ::LER; 274 else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)) 275 Opcode = SystemZ::LDR; 276 else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)) 277 Opcode = SystemZ::LXR; 278 else 279 llvm_unreachable("Impossible reg-to-reg copy"); 280 281 BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 282 .addReg(SrcReg, getKillRegState(KillSrc)); 283 } 284 285 void 286 SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 287 MachineBasicBlock::iterator MBBI, 288 unsigned SrcReg, bool isKill, 289 int FrameIdx, 290 const TargetRegisterClass *RC, 291 const TargetRegisterInfo *TRI) const { 292 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 293 294 // Callers may expect a single instruction, so keep 128-bit moves 295 // together for now and lower them after register allocation. 296 unsigned LoadOpcode, StoreOpcode; 297 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 298 addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) 299 .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 300 } 301 302 void 303 SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 304 MachineBasicBlock::iterator MBBI, 305 unsigned DestReg, int FrameIdx, 306 const TargetRegisterClass *RC, 307 const TargetRegisterInfo *TRI) const { 308 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 309 310 // Callers may expect a single instruction, so keep 128-bit moves 311 // together for now and lower them after register allocation. 312 unsigned LoadOpcode, StoreOpcode; 313 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 314 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), 315 FrameIdx); 316 } 317 318 bool 319 SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 320 switch (MI->getOpcode()) { 321 case SystemZ::L128: 322 splitMove(MI, SystemZ::LG); 323 return true; 324 325 case SystemZ::ST128: 326 splitMove(MI, SystemZ::STG); 327 return true; 328 329 case SystemZ::LX: 330 splitMove(MI, SystemZ::LD); 331 return true; 332 333 case SystemZ::STX: 334 splitMove(MI, SystemZ::STD); 335 return true; 336 337 case SystemZ::ADJDYNALLOC: 338 splitAdjDynAlloc(MI); 339 return true; 340 341 default: 342 return false; 343 } 344 } 345 346 bool SystemZInstrInfo:: 347 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 348 assert(Cond.size() == 1 && "Invalid branch condition!"); 349 Cond[0].setImm(Cond[0].getImm() ^ SystemZ::CCMASK_ANY); 350 return false; 351 } 352 353 uint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { 354 if (MI->getOpcode() == TargetOpcode::INLINEASM) { 355 const MachineFunction *MF = MI->getParent()->getParent(); 356 const char *AsmStr = MI->getOperand(0).getSymbolName(); 357 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 358 } 359 return MI->getDesc().getSize(); 360 } 361 362 SystemZII::Branch 363 SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { 364 switch (MI->getOpcode()) { 365 case SystemZ::BR: 366 case SystemZ::J: 367 case SystemZ::JG: 368 return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, 369 &MI->getOperand(0)); 370 371 case SystemZ::BRC: 372 case SystemZ::BRCL: 373 return SystemZII::Branch(SystemZII::BranchNormal, 374 MI->getOperand(0).getImm(), &MI->getOperand(1)); 375 376 case SystemZ::CIJ: 377 case SystemZ::CRJ: 378 return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), 379 &MI->getOperand(3)); 380 381 case SystemZ::CGIJ: 382 case SystemZ::CGRJ: 383 return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), 384 &MI->getOperand(3)); 385 386 default: 387 llvm_unreachable("Unrecognized branch opcode"); 388 } 389 } 390 391 void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 392 unsigned &LoadOpcode, 393 unsigned &StoreOpcode) const { 394 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 395 LoadOpcode = SystemZ::L; 396 StoreOpcode = SystemZ::ST32; 397 } else if (RC == &SystemZ::GR64BitRegClass || 398 RC == &SystemZ::ADDR64BitRegClass) { 399 LoadOpcode = SystemZ::LG; 400 StoreOpcode = SystemZ::STG; 401 } else if (RC == &SystemZ::GR128BitRegClass || 402 RC == &SystemZ::ADDR128BitRegClass) { 403 LoadOpcode = SystemZ::L128; 404 StoreOpcode = SystemZ::ST128; 405 } else if (RC == &SystemZ::FP32BitRegClass) { 406 LoadOpcode = SystemZ::LE; 407 StoreOpcode = SystemZ::STE; 408 } else if (RC == &SystemZ::FP64BitRegClass) { 409 LoadOpcode = SystemZ::LD; 410 StoreOpcode = SystemZ::STD; 411 } else if (RC == &SystemZ::FP128BitRegClass) { 412 LoadOpcode = SystemZ::LX; 413 StoreOpcode = SystemZ::STX; 414 } else 415 llvm_unreachable("Unsupported regclass to load or store"); 416 } 417 418 unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 419 int64_t Offset) const { 420 const MCInstrDesc &MCID = get(Opcode); 421 int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 422 if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 423 // Get the instruction to use for unsigned 12-bit displacements. 424 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 425 if (Disp12Opcode >= 0) 426 return Disp12Opcode; 427 428 // All address-related instructions can use unsigned 12-bit 429 // displacements. 430 return Opcode; 431 } 432 if (isInt<20>(Offset) && isInt<20>(Offset2)) { 433 // Get the instruction to use for signed 20-bit displacements. 434 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 435 if (Disp20Opcode >= 0) 436 return Disp20Opcode; 437 438 // Check whether Opcode allows signed 20-bit displacements. 439 if (MCID.TSFlags & SystemZII::Has20BitOffset) 440 return Opcode; 441 } 442 return 0; 443 } 444 445 unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, 446 const MachineInstr *MI) const { 447 switch (Opcode) { 448 case SystemZ::CR: 449 return SystemZ::CRJ; 450 case SystemZ::CGR: 451 return SystemZ::CGRJ; 452 case SystemZ::CHI: 453 return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; 454 case SystemZ::CGHI: 455 return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; 456 default: 457 return 0; 458 } 459 } 460 461 void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 462 MachineBasicBlock::iterator MBBI, 463 unsigned Reg, uint64_t Value) const { 464 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 465 unsigned Opcode; 466 if (isInt<16>(Value)) 467 Opcode = SystemZ::LGHI; 468 else if (SystemZ::isImmLL(Value)) 469 Opcode = SystemZ::LLILL; 470 else if (SystemZ::isImmLH(Value)) { 471 Opcode = SystemZ::LLILH; 472 Value >>= 16; 473 } else { 474 assert(isInt<32>(Value) && "Huge values not handled yet"); 475 Opcode = SystemZ::LGFI; 476 } 477 BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 478 } 479