SystemZInstrInfo.cpp revision d50bcb2162a529534da42748ab4a418bfc9aaf06
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 22using namespace llvm; 23 24SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 25 : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 26 RI(tm, *this) { 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. 31void 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. 63void 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. 83static 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 95unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 96 int &FrameIndex) const { 97 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 98} 99 100unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 101 int &FrameIndex) const { 102 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 103} 104 105bool 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 195unsigned 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 217unsigned 218SystemZInstrInfo::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 252void 253SystemZInstrInfo::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 285void 286SystemZInstrInfo::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 302void 303SystemZInstrInfo::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 318bool 319SystemZInstrInfo::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 346bool SystemZInstrInfo:: 347ReverseBranchCondition(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 353uint64_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 362SystemZII::Branch 363SystemZInstrInfo::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::CRJ: 377 return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), 378 &MI->getOperand(3)); 379 380 case SystemZ::CGRJ: 381 return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), 382 &MI->getOperand(3)); 383 384 default: 385 llvm_unreachable("Unrecognized branch opcode"); 386 } 387} 388 389void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 390 unsigned &LoadOpcode, 391 unsigned &StoreOpcode) const { 392 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 393 LoadOpcode = SystemZ::L; 394 StoreOpcode = SystemZ::ST32; 395 } else if (RC == &SystemZ::GR64BitRegClass || 396 RC == &SystemZ::ADDR64BitRegClass) { 397 LoadOpcode = SystemZ::LG; 398 StoreOpcode = SystemZ::STG; 399 } else if (RC == &SystemZ::GR128BitRegClass || 400 RC == &SystemZ::ADDR128BitRegClass) { 401 LoadOpcode = SystemZ::L128; 402 StoreOpcode = SystemZ::ST128; 403 } else if (RC == &SystemZ::FP32BitRegClass) { 404 LoadOpcode = SystemZ::LE; 405 StoreOpcode = SystemZ::STE; 406 } else if (RC == &SystemZ::FP64BitRegClass) { 407 LoadOpcode = SystemZ::LD; 408 StoreOpcode = SystemZ::STD; 409 } else if (RC == &SystemZ::FP128BitRegClass) { 410 LoadOpcode = SystemZ::LX; 411 StoreOpcode = SystemZ::STX; 412 } else 413 llvm_unreachable("Unsupported regclass to load or store"); 414} 415 416unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 417 int64_t Offset) const { 418 const MCInstrDesc &MCID = get(Opcode); 419 int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 420 if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 421 // Get the instruction to use for unsigned 12-bit displacements. 422 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 423 if (Disp12Opcode >= 0) 424 return Disp12Opcode; 425 426 // All address-related instructions can use unsigned 12-bit 427 // displacements. 428 return Opcode; 429 } 430 if (isInt<20>(Offset) && isInt<20>(Offset2)) { 431 // Get the instruction to use for signed 20-bit displacements. 432 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 433 if (Disp20Opcode >= 0) 434 return Disp20Opcode; 435 436 // Check whether Opcode allows signed 20-bit displacements. 437 if (MCID.TSFlags & SystemZII::Has20BitOffset) 438 return Opcode; 439 } 440 return 0; 441} 442 443unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode) const { 444 switch (Opcode) { 445 case SystemZ::CR: 446 return SystemZ::CRJ; 447 case SystemZ::CGR: 448 return SystemZ::CGRJ; 449 default: 450 return 0; 451 } 452} 453 454void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 455 MachineBasicBlock::iterator MBBI, 456 unsigned Reg, uint64_t Value) const { 457 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 458 unsigned Opcode; 459 if (isInt<16>(Value)) 460 Opcode = SystemZ::LGHI; 461 else if (SystemZ::isImmLL(Value)) 462 Opcode = SystemZ::LLILL; 463 else if (SystemZ::isImmLH(Value)) { 464 Opcode = SystemZ::LLILH; 465 Value >>= 16; 466 } else { 467 assert(isInt<32>(Value) && "Huge values not handled yet"); 468 Opcode = SystemZ::LGFI; 469 } 470 BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 471} 472