SystemZInstrInfo.cpp revision 6cf3cfa0ab1da0c52730fec103bbc69eb0370081
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" 161ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford#include "llvm/CodeGen/MachineRegisterInfo.h" 1744b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford#include "llvm/Target/TargetMachine.h" 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRINFO_CTOR 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRMAP_INFO 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenInstrInfo.inc" 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 27fc61b6f111af79662baf273c40593a1e8f4dc719Bill Wendling RI(tm) { 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MI is a 128-bit load or store. Split it into two 64-bit loads or stores, 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// each having the opcode given by NewOpcode. 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode) const { 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get two load or store instructions. Use the original instruction for one 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // of them (arbitarily the second here) and create a clone for the other. 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstr *EarlierMI = MF.CloneMachineInstr(MI); 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->insert(MI, EarlierMI); 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the two 64-bit registers. 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighRegOp = EarlierMI->getOperand(0); 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowRegOp = MI->getOperand(0); 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high)); 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low)); 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The address in the first (high) instruction is already correct. 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust the offset in the second (low) instruction. 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowOffsetOp = MI->getOperand(2); 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set the opcodes. 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(HighOpcode && LowOpcode && "Both offsets should be in range"); 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EarlierMI->setDesc(get(HighOpcode)); 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(LowOpcode)); 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Split ADJDYNALLOC instruction MI. 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &OffsetMO = MI->getOperand(2); 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Offset = (MFFrame->getMaxCallFrameSize() + 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMC::CallFrameSize + 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.getImm()); 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(NewOpcode && "No support for huge argument lists yet"); 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(NewOpcode)); 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.setImm(Offset); 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If MI is a simple load or store for a frame object, return the register 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// it loads or stores and set FrameIndex to the index of the frame object. 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return 0 otherwise. 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 841ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic int isSimpleMove(const MachineInstr *MI, int &FrameIndex, 851ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Flag) { 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = MI->getDesc(); 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((MCID.TSFlags & Flag) && 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(1).isFI() && 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(2).getImm() == 0 && 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(3).getReg() == 0) { 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIndex = MI->getOperand(1).getIndex(); 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MI->getOperand(0).getReg(); 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandifordbool SystemZInstrInfo::isStackSlotCopy(const MachineInstr *MI, 10871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &DestFrameIndex, 10971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &SrcFrameIndex) const { 11071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check for MVC 0(Length,FI1),0(FI2) 11171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford const MachineFrameInfo *MFI = MI->getParent()->getParent()->getFrameInfo(); 11271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MI->getOpcode() != SystemZ::MVC || 11371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(0).isFI() || 11471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(1).getImm() != 0 || 11571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(3).isFI() || 11671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(4).getImm() != 0) 11771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 11871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 11971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check that Length covers the full slots. 12071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int64_t Length = MI->getOperand(2).getImm(); 12171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI1 = MI->getOperand(0).getIndex(); 12271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI2 = MI->getOperand(3).getIndex(); 12371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MFI->getObjectSize(FI1) != Length || 12471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MFI->getObjectSize(FI2) != Length) 12571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 12671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 12771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford DestFrameIndex = FI1; 12871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford SrcFrameIndex = FI2; 12971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return true; 13071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford} 13171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&TBB, 1341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&FBB, 1351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<MachineOperand> &Cond, 1361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool AllowModify) const { 1371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 1381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start from the bottom of the block and work up, examining the 1401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // terminator instructions. 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 1421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, when we see a non-terminator instruction, we're 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // done. 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isUnpredicatedTerminator(I)) 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A terminator that isn't a branch can't easily be handled by this 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // analysis. 15406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Can't handle indirect branches. 15806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford SystemZII::Branch Branch(getBranchInfo(I)); 15906c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!Branch.Target->isMBB()) 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 162d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // Punt on compound branches. 163d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford if (Branch.Type != SystemZII::BranchNormal) 164d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return true; 165d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 16606c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (Branch.CCMask == SystemZ::CCMASK_ANY) { 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unconditional branches. 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!AllowModify) { 16906c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the block has any instructions after a JMP, delete them. 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (llvm::next(I) != MBB.end()) 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm::next(I)->eraseFromParent(); 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond.clear(); 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = 0; 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Delete the JMP if it's equivalent to a fall-through. 18106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TBB = 0; 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TBB is used to indicate the unconditinal destination. 18906c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, handle the first conditional branch. 1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: add X86-style branch swap 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = TBB; 19706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 19806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle subsequent conditional branches. 2031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Cond.size() == 1); 2041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB); 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only handle the case where all conditional branches branch to the same 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // destination. 20806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (TBB != Branch.Target->getMBB()) 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the conditions are the same, we can leave them alone. 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldCond = Cond[0].getImm(); 21306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (OldCond == Branch.CCMask) 2141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Try combining conditions like X86 does. Should be easy on Z! 2171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 2201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 23106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 23306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!getBranchInfo(I).Target->isMBB()) 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Remove the branch. 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FBB, 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<MachineOperand> &Cond, 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL) const { 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // In this function we output 32-bit branches, which should always 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // have enough range. They can be shortened and relaxed by later code 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the pipeline, if desired. 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Shouldn't be a fall through. 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert((Cond.size() == 1 || Cond.size() == 0) && 2561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "SystemZ branch conditions have one component!"); 2571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 2591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unconditional branch? 2601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(!FBB && "Unconditional branch with multiple successors!"); 26144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); 2621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 1; 2631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Conditional branch. 2661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 2671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CC = Cond[0].getImm(); 26844b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::BRC)).addImm(CC).addMBB(TBB); 2691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (FBB) { 2721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Two-way Conditional branch. Insert the second branch. 27344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); 2741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 2801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 2811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, DebugLoc DL, 2821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, unsigned SrcReg, 2831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool KillSrc) const { 2841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too. 2851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) { 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high), 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc); 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low), 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc); 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Everything else needs only one instruction. 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR32BitRegClass.contains(DestReg, SrcReg)) 2961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LR; 2971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) 2981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGR; 2991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)) 3001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LER; 3011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)) 3021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LDR; 3031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)) 3041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LXR; 3051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Impossible reg-to-reg copy"); 3071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 3091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(KillSrc)); 3101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 3131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 3141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 3151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SrcReg, bool isKill, 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FrameIdx, 3171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 3181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 3221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 3231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 3271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 3301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, int FrameIdx, 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIdx); 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3451ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// Return true if MI is a simple load or store with a 12-bit displacement 3461ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 3471ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) { 3481ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MCInstrDesc &MCID = MI->getDesc(); 3491ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return ((MCID.TSFlags & Flag) && 3501ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford isUInt<12>(MI->getOperand(2).getImm()) && 3511ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MI->getOperand(3).getReg() == 0); 3521ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 3531ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 3541ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 3551ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 3561ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr *MI, 3571ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 3581ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford int FrameIndex) const { 3591ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MachineFrameInfo *MFI = MF.getFrameInfo(); 3601ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Size = MFI->getObjectSize(FrameIndex); 3611ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 3621ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Eary exit for cases we don't care about 3631ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (Ops.size() != 1) 3641ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 3651ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 3661ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned OpNum = Ops[0]; 367985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi assert(Size == MF.getRegInfo() 368985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi .getRegClass(MI->getOperand(OpNum).getReg())->getSize() && 36924dd7dbe7f2a3338a20314b3863f6b738cc1c298Benjamin Kramer "Invalid size combination"); 3701ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 3716cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned Opcode = MI->getOpcode(); 3726cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) { 3736cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op0IsGPR = (Opcode == SystemZ::LGDR); 3746cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op1IsGPR = (Opcode == SystemZ::LDGR); 3756cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the destination of an LDGR or LGDR, store the 3766cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // source register instead. 3776cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 0) { 3786cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD; 3796cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(StoreOpcode)) 3806cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addOperand(MI->getOperand(1)).addFrameIndex(FrameIndex) 3816cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addImm(0).addReg(0); 3826cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 3836cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the source of an LDGR or LGDR, load the 3846cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // destination register instead. 3856cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 1) { 3866cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD; 3876cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned Dest = MI->getOperand(0).getReg(); 3886cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(LoadOpcode), Dest) 3896cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addReg(0); 3906cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 3916cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 3926cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford 3931ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Look for cases where the source of a simple store or the destination 3941ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // of a simple load is being spilled. Try to use MVC instead. 3951ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // 3961ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Although MVC is in practice a fast choice in these cases, it is still 3971ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // logically a bytewise copy. This means that we cannot use it if the 3981ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // load or store is volatile. It also means that the transformation is 3991ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // not valid in cases where the two memories partially overlap; however, 4001ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // that is not a problem here, because we know that one of the memories 4011ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // is a full frame index. 4021ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (OpNum == 0 && MI->hasOneMemOperand()) { 4031ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineMemOperand *MMO = *MI->memoperands_begin(); 4041ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (MMO->getSize() == Size && !MMO->isVolatile()) { 4051ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of loads. 406cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXLoad)) { 4071ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 408e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addImm(Size) 4091ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 410e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 4111ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 4121ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of stores. 413cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXStore)) { 4141ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 4151ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 416e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addImm(Size).addFrameIndex(FrameIndex).addImm(0) 417e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 4181ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 4191ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 4201ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 4211ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 422fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // If the spilled operand is the final one, try to change <INSN>R 423fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // into <INSN>. 4246cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford int MemOpcode = SystemZ::getMemOpcode(Opcode); 425fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemOpcode >= 0) { 426fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford unsigned NumOps = MI->getNumExplicitOperands(); 427fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (OpNum == NumOps - 1) { 428fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford const MCInstrDesc &MemDesc = get(MemOpcode); 429fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t AccessBytes = SystemZII::getAccessSize(MemDesc.TSFlags); 430fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes != 0 && "Size of access should be known"); 431fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes <= Size && "Access outside the frame index"); 432fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t Offset = Size - AccessBytes; 433fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(MemOpcode)); 434fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford for (unsigned I = 0; I < OpNum; ++I) 435fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addOperand(MI->getOperand(I)); 436fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addFrameIndex(FrameIndex).addImm(Offset); 437fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemDesc.TSFlags & SystemZII::HasIndex) 438fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addReg(0); 439fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford return MIB; 440fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 441fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 442fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford 4431ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 4441ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 4451ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 4461ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 4471ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, 4481ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 4491ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr* LoadMI) const { 4501ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 4511ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 4521ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::L128: 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LG); 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ST128: 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STG); 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::LX: 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LD); 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::STX: 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STD); 4701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJDYNALLOC: 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitAdjDynAlloc(MI); 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo:: 4821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 4831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Cond.size() == 1 && "Invalid branch condition!"); 4841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond[0].setImm(Cond[0].getImm() ^ SystemZ::CCMASK_ANY); 4851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 48844b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiforduint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { 48944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford if (MI->getOpcode() == TargetOpcode::INLINEASM) { 49044b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const MachineFunction *MF = MI->getParent()->getParent(); 49144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const char *AsmStr = MI->getOperand(0).getSymbolName(); 49244b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 49344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford } 49444b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return MI->getDesc().getSize(); 49544b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford} 49644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford 49706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZII::Branch 49806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { 4991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 5001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BR: 5011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::J: 5021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::JG: 503d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, 504d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(0)); 5051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRC: 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRCL: 508d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, 509d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford MI->getOperand(0).getImm(), &MI->getOperand(1)); 510d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 5112d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CIJ: 512d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CRJ: 513d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), 514d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(3)); 515d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 5162d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGIJ: 517d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGRJ: 518d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), 519d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford &MI->getOperand(3)); 5201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 52206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford llvm_unreachable("Unrecognized branch opcode"); 5231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 5271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &LoadOpcode, 5281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &StoreOpcode) const { 5291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 5301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L; 5311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST32; 5321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR64BitRegClass || 5331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR64BitRegClass) { 5341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LG; 5351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STG; 5361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR128BitRegClass || 5371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR128BitRegClass) { 5381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L128; 5391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST128; 5401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP32BitRegClass) { 5411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LE; 5421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STE; 5431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP64BitRegClass) { 5441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LD; 5451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STD; 5461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP128BitRegClass) { 5471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LX; 5481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STX; 5491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 5501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported regclass to load or store"); 5511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset) const { 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = get(Opcode); 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for unsigned 12-bit displacements. 5591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 5601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp12Opcode >= 0) 5611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp12Opcode; 5621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // All address-related instructions can use unsigned 12-bit 5641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacements. 5651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 5661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(Offset) && isInt<20>(Offset2)) { 5681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for signed 20-bit displacements. 5691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 5701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp20Opcode >= 0) 5711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp20Opcode; 5721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether Opcode allows signed 20-bit displacements. 5741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MCID.TSFlags & SystemZII::Has20BitOffset) 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 5761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5802d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandifordunsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, 5812d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford const MachineInstr *MI) const { 582d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford switch (Opcode) { 583d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CR: 584d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CRJ; 585d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGR: 586d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CGRJ; 5872d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CHI: 5882d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; 5892d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGHI: 5902d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; 591d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford default: 592d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return 0; 593d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford } 594d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford} 595d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg, uint64_t Value) const { 5991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 6011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(Value)) 6021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGHI; 6031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLL(Value)) 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILL; 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLH(Value)) { 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILH; 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value >>= 16; 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(isInt<32>(Value) && "Huge values not handled yet"); 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGFI; 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 6131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 614