SystemZInstrInfo.cpp revision 2d664abbfca8b9fa3d99e8a2f74bd52faf007f12
11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZInstrInfo.cpp - SystemZ instruction information ------------===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file contains the SystemZ implementation of the TargetInstrInfo class. 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrInfo.h" 151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrBuilder.h" 1644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford#include "llvm/Target/TargetMachine.h" 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRINFO_CTOR 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRMAP_INFO 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenInstrInfo.inc" 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI(tm, *this) { 271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MI is a 128-bit load or store. Split it into two 64-bit loads or stores, 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// each having the opcode given by NewOpcode. 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode) const { 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get two load or store instructions. Use the original instruction for one 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // of them (arbitarily the second here) and create a clone for the other. 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstr *EarlierMI = MF.CloneMachineInstr(MI); 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->insert(MI, EarlierMI); 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the two 64-bit registers. 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighRegOp = EarlierMI->getOperand(0); 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowRegOp = MI->getOperand(0); 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high)); 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low)); 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The address in the first (high) instruction is already correct. 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust the offset in the second (low) instruction. 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowOffsetOp = MI->getOperand(2); 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set the opcodes. 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(HighOpcode && LowOpcode && "Both offsets should be in range"); 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EarlierMI->setDesc(get(HighOpcode)); 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(LowOpcode)); 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Split ADJDYNALLOC instruction MI. 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &OffsetMO = MI->getOperand(2); 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Offset = (MFFrame->getMaxCallFrameSize() + 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMC::CallFrameSize + 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.getImm()); 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(NewOpcode && "No support for huge argument lists yet"); 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(NewOpcode)); 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.setImm(Offset); 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If MI is a simple load or store for a frame object, return the register 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// it loads or stores and set FrameIndex to the index of the frame object. 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return 0 otherwise. 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic int isSimpleMove(const MachineInstr *MI, int &FrameIndex, int Flag) { 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = MI->getDesc(); 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((MCID.TSFlags & Flag) && 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(1).isFI() && 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(2).getImm() == 0 && 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(3).getReg() == 0) { 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIndex = MI->getOperand(1).getIndex(); 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MI->getOperand(0).getReg(); 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&TBB, 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&FBB, 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<MachineOperand> &Cond, 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool AllowModify) const { 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start from the bottom of the block and work up, examining the 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // terminator instructions. 1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 1161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 1171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 1181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, when we see a non-terminator instruction, we're 1211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // done. 1221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isUnpredicatedTerminator(I)) 1231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 1241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A terminator that isn't a branch can't easily be handled by this 1261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // analysis. 12706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 1281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Can't handle indirect branches. 13106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford SystemZII::Branch Branch(getBranchInfo(I)); 13206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!Branch.Target->isMBB()) 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 135d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // Punt on compound branches. 136d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford if (Branch.Type != SystemZII::BranchNormal) 137d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return true; 138d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 13906c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (Branch.CCMask == SystemZ::CCMASK_ANY) { 1401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unconditional branches. 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!AllowModify) { 14206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the block has any instructions after a JMP, delete them. 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (llvm::next(I) != MBB.end()) 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm::next(I)->eraseFromParent(); 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond.clear(); 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = 0; 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Delete the JMP if it's equivalent to a fall-through. 15406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TBB = 0; 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TBB is used to indicate the unconditinal destination. 16206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, handle the first conditional branch. 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: add X86-style branch swap 1691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = TBB; 17006c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 17106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle subsequent conditional branches. 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Cond.size() == 1); 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB); 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only handle the case where all conditional branches branch to the same 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // destination. 18106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (TBB != Branch.Target->getMBB()) 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the conditions are the same, we can leave them alone. 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldCond = Cond[0].getImm(); 18606c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (OldCond == Branch.CCMask) 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Try combining conditions like X86 does. Should be easy on Z! 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 2021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 2031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 20406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 20606c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!getBranchInfo(I).Target->isMBB()) 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Remove the branch. 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned 2181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 2191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FBB, 2201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<MachineOperand> &Cond, 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL) const { 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // In this function we output 32-bit branches, which should always 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // have enough range. They can be shortened and relaxed by later code 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the pipeline, if desired. 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Shouldn't be a fall through. 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert((Cond.size() == 1 || Cond.size() == 0) && 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "SystemZ branch conditions have one component!"); 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unconditional branch? 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(!FBB && "Unconditional branch with multiple successors!"); 23444b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 1; 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Conditional branch. 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CC = Cond[0].getImm(); 24144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::BRC)).addImm(CC).addMBB(TBB); 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (FBB) { 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Two-way Conditional branch. Insert the second branch. 24644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, DebugLoc DL, 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, unsigned SrcReg, 2561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool KillSrc) const { 2571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too. 2581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) { 2591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high), 2601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc); 2611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low), 2621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc); 2631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 2641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Everything else needs only one instruction. 2671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 2681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR32BitRegClass.contains(DestReg, SrcReg)) 2691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LR; 2701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) 2711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGR; 2721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)) 2731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LER; 2741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)) 2751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LDR; 2761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)) 2771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LXR; 2781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 2791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Impossible reg-to-reg copy"); 2801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 2821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(KillSrc)); 2831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SrcReg, bool isKill, 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FrameIdx, 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 2961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 2971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 2981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) 2991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 3001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 3031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 3041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 3051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, int FrameIdx, 3061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 3071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 3081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 3091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 3111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 3121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 3131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 3141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), 3151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIdx); 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 3211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::L128: 3221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LG); 3231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ST128: 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STG); 3271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::LX: 3301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LD); 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::STX: 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STD); 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJDYNALLOC: 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitAdjDynAlloc(MI); 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo:: 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Cond.size() == 1 && "Invalid branch condition!"); 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond[0].setImm(Cond[0].getImm() ^ SystemZ::CCMASK_ANY); 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 35344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiforduint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { 35444b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford if (MI->getOpcode() == TargetOpcode::INLINEASM) { 35544b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const MachineFunction *MF = MI->getParent()->getParent(); 35644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const char *AsmStr = MI->getOperand(0).getSymbolName(); 35744b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 35844b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford } 35944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return MI->getDesc().getSize(); 36044b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford} 36144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford 36206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZII::Branch 36306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BR: 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::J: 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::JG: 368d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, 369d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(0)); 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRC: 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRCL: 373d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, 374d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford MI->getOperand(0).getImm(), &MI->getOperand(1)); 375d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 3762d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CIJ: 377d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CRJ: 378d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), 379d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(3)); 380d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 3812d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGIJ: 382d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGRJ: 383d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), 384d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(3)); 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 38706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford llvm_unreachable("Unrecognized branch opcode"); 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &LoadOpcode, 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &StoreOpcode) const { 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L; 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST32; 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR64BitRegClass || 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR64BitRegClass) { 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LG; 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STG; 4011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR128BitRegClass || 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR128BitRegClass) { 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L128; 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST128; 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP32BitRegClass) { 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LE; 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STE; 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP64BitRegClass) { 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LD; 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STD; 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP128BitRegClass) { 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LX; 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STX; 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported regclass to load or store"); 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset) const { 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = get(Opcode); 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for unsigned 12-bit displacements. 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp12Opcode >= 0) 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp12Opcode; 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // All address-related instructions can use unsigned 12-bit 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacements. 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 4311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(Offset) && isInt<20>(Offset2)) { 4331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for signed 20-bit displacements. 4341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 4351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp20Opcode >= 0) 4361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp20Opcode; 4371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether Opcode allows signed 20-bit displacements. 4391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MCID.TSFlags & SystemZII::Has20BitOffset) 4401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 4411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 4431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4452d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandifordunsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, 4462d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford const MachineInstr *MI) const { 447d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford switch (Opcode) { 448d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CR: 449d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CRJ; 450d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGR: 451d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CGRJ; 4522d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CHI: 4532d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; 4542d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGHI: 4552d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; 456d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford default: 457d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return 0; 458d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford } 459d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford} 460d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg, uint64_t Value) const { 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(Value)) 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGHI; 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLL(Value)) 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILL; 4701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLH(Value)) { 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILH; 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value >>= 16; 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(isInt<32>(Value) && "Huge values not handled yet"); 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGFI; 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 479