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