SystemZInstrInfo.cpp revision 9b05c709c65ba05645853ca49bc2a1ea8b554f37
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" 1593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford#include "SystemZTargetMachine.h" 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrBuilder.h" 1793c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford#include "llvm/CodeGen/LiveVariables.h" 181ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford#include "llvm/CodeGen/MachineRegisterInfo.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRINFO_CTOR 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRMAP_INFO 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenInstrInfo.inc" 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Return a mask with Count low bits set. 27b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic uint64_t allOnes(unsigned int Count) { 28b3f912b510f8040690864126351b7021980558bbRichard Sandiford return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1; 29b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 30b3f912b510f8040690864126351b7021980558bbRichard Sandiford 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 3393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford RI(tm), TM(tm) { 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MI is a 128-bit load or store. Split it into two 64-bit loads or stores, 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// each having the opcode given by NewOpcode. 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode) const { 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get two load or store instructions. Use the original instruction for one 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // of them (arbitarily the second here) and create a clone for the other. 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstr *EarlierMI = MF.CloneMachineInstr(MI); 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->insert(MI, EarlierMI); 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the two 64-bit registers. 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighRegOp = EarlierMI->getOperand(0); 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowRegOp = MI->getOperand(0); 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high)); 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low)); 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The address in the first (high) instruction is already correct. 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust the offset in the second (low) instruction. 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowOffsetOp = MI->getOperand(2); 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set the opcodes. 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(HighOpcode && LowOpcode && "Both offsets should be in range"); 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EarlierMI->setDesc(get(HighOpcode)); 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(LowOpcode)); 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Split ADJDYNALLOC instruction MI. 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &OffsetMO = MI->getOperand(2); 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Offset = (MFFrame->getMaxCallFrameSize() + 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMC::CallFrameSize + 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.getImm()); 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(NewOpcode && "No support for huge argument lists yet"); 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(NewOpcode)); 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.setImm(Offset); 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If MI is a simple load or store for a frame object, return the register 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// it loads or stores and set FrameIndex to the index of the frame object. 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return 0 otherwise. 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 901ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic int isSimpleMove(const MachineInstr *MI, int &FrameIndex, 911ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Flag) { 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = MI->getDesc(); 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((MCID.TSFlags & Flag) && 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(1).isFI() && 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(2).getImm() == 0 && 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(3).getReg() == 0) { 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIndex = MI->getOperand(1).getIndex(); 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MI->getOperand(0).getReg(); 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandifordbool SystemZInstrInfo::isStackSlotCopy(const MachineInstr *MI, 11471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &DestFrameIndex, 11571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &SrcFrameIndex) const { 11671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check for MVC 0(Length,FI1),0(FI2) 11771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford const MachineFrameInfo *MFI = MI->getParent()->getParent()->getFrameInfo(); 11871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MI->getOpcode() != SystemZ::MVC || 11971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(0).isFI() || 12071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(1).getImm() != 0 || 12171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(3).isFI() || 12271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(4).getImm() != 0) 12371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 12471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 12571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check that Length covers the full slots. 12671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int64_t Length = MI->getOperand(2).getImm(); 12771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI1 = MI->getOperand(0).getIndex(); 12871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI2 = MI->getOperand(3).getIndex(); 12971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MFI->getObjectSize(FI1) != Length || 13071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MFI->getObjectSize(FI2) != Length) 13171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 13271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 13371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford DestFrameIndex = FI1; 13471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford SrcFrameIndex = FI2; 13571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return true; 13671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford} 13771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 1381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 1391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&TBB, 1401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&FBB, 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<MachineOperand> &Cond, 1421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool AllowModify) const { 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start from the bottom of the block and work up, examining the 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // terminator instructions. 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, when we see a non-terminator instruction, we're 1541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // done. 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isUnpredicatedTerminator(I)) 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A terminator that isn't a branch can't easily be handled by this 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // analysis. 16006c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Can't handle indirect branches. 16406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford SystemZII::Branch Branch(getBranchInfo(I)); 16506c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!Branch.Target->isMBB()) 1661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 168d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // Punt on compound branches. 169d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford if (Branch.Type != SystemZII::BranchNormal) 170d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return true; 171d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 17206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (Branch.CCMask == SystemZ::CCMASK_ANY) { 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unconditional branches. 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!AllowModify) { 17506c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the block has any instructions after a JMP, delete them. 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (llvm::next(I) != MBB.end()) 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm::next(I)->eraseFromParent(); 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond.clear(); 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = 0; 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Delete the JMP if it's equivalent to a fall-through. 18706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TBB = 0; 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TBB is used to indicate the unconditinal destination. 19506c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, handle the first conditional branch. 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: add X86-style branch swap 2021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = TBB; 20306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 2046824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCValid)); 20506c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle subsequent conditional branches. 2106824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch"); 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only handle the case where all conditional branches branch to the same 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // destination. 21406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (TBB != Branch.Target->getMBB()) 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the conditions are the same, we can leave them alone. 2186824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned OldCCValid = Cond[0].getImm(); 2196824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned OldCCMask = Cond[1].getImm(); 2206824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask) 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Try combining conditions like X86 does. Should be easy on Z! 2246824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return false; 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 23906c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 24106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!getBranchInfo(I).Target->isMBB()) 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Remove the branch. 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2526824f127f90197b26af93cf5d6c13b7941567e54Richard Sandifordbool SystemZInstrInfo:: 2536824f127f90197b26af93cf5d6c13b7941567e54Richard SandifordReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 2546824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Cond.size() == 2 && "Invalid condition"); 2556824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm()); 2566824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return false; 2576824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford} 2586824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford 2591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned 2601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 2611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FBB, 2621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<MachineOperand> &Cond, 2631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL) const { 2641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // In this function we output 32-bit branches, which should always 2651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // have enough range. They can be shortened and relaxed by later code 2661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the pipeline, if desired. 2671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Shouldn't be a fall through. 2691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 2706824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert((Cond.size() == 2 || Cond.size() == 0) && 2711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "SystemZ branch conditions have one component!"); 2721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 2741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unconditional branch? 2751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(!FBB && "Unconditional branch with multiple successors!"); 27644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); 2771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 1; 2781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Conditional branch. 2811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 2826824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = Cond[0].getImm(); 2836824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = Cond[1].getImm(); 2846824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::BRC)) 2856824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(TBB); 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (FBB) { 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Two-way Conditional branch. Insert the second branch. 29044b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 296bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford// If Opcode is a move that has a conditional variant, return that variant, 297bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford// otherwise return 0. 298bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordstatic unsigned getConditionalMove(unsigned Opcode) { 299bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford switch (Opcode) { 300bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford case SystemZ::LR: return SystemZ::LOCR; 301bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford case SystemZ::LGR: return SystemZ::LOCGR; 302bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford default: return 0; 303bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 304bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 305bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 306bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo::isPredicable(MachineInstr *MI) const { 307bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned Opcode = MI->getOpcode(); 308bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford if (TM.getSubtargetImpl()->hasLoadStoreOnCond() && 309bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford getConditionalMove(Opcode)) 310bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return true; 311bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 312bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 313bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 314bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 315bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordisProfitableToIfCvt(MachineBasicBlock &MBB, 316bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCycles, unsigned ExtraPredCycles, 317bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const BranchProbability &Probability) const { 318bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford // For now only convert single instructions. 319bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return NumCycles == 1; 320bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 321bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 322bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 323bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordisProfitableToIfCvt(MachineBasicBlock &TMBB, 324bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCyclesT, unsigned ExtraPredCyclesT, 325bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford MachineBasicBlock &FMBB, 326bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCyclesF, unsigned ExtraPredCyclesF, 327bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const BranchProbability &Probability) const { 328bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford // For now avoid converting mutually-exclusive cases. 329bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 330bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 331bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 332bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 333bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordPredicateInstruction(MachineInstr *MI, 334bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const SmallVectorImpl<MachineOperand> &Pred) const { 3356824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Pred.size() == 2 && "Invalid condition"); 3366824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = Pred[0].getImm(); 3376824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = Pred[1].getImm(); 338bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford assert(CCMask > 0 && CCMask < 15 && "Invalid predicate"); 339bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned Opcode = MI->getOpcode(); 340bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford if (TM.getSubtargetImpl()->hasLoadStoreOnCond()) { 341bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford if (unsigned CondOpcode = getConditionalMove(Opcode)) { 342bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford MI->setDesc(get(CondOpcode)); 3436824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MachineInstrBuilder(*MI->getParent()->getParent(), MI) 3448f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addImm(CCValid).addImm(CCMask) 3458f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addReg(SystemZ::CC, RegState::Implicit);; 346bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return true; 347bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 348bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 349bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 350bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 351bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, DebugLoc DL, 3551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, unsigned SrcReg, 3561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool KillSrc) const { 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too. 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) { 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high), 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc); 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low), 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc); 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Everything else needs only one instruction. 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR32BitRegClass.contains(DestReg, SrcReg)) 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LR; 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGR; 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)) 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LER; 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)) 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LDR; 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)) 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LXR; 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Impossible reg-to-reg copy"); 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(KillSrc)); 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 3871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SrcReg, bool isKill, 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FrameIdx, 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, int FrameIdx, 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIdx); 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4181ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// Return true if MI is a simple load or store with a 12-bit displacement 4191ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 4201ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) { 4211ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MCInstrDesc &MCID = MI->getDesc(); 4221ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return ((MCID.TSFlags & Flag) && 4231ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford isUInt<12>(MI->getOperand(2).getImm()) && 4241ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MI->getOperand(3).getReg() == 0); 4251ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 4261ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 427b3f912b510f8040690864126351b7021980558bbRichard Sandifordnamespace { 428b3f912b510f8040690864126351b7021980558bbRichard Sandiford struct LogicOp { 429b3f912b510f8040690864126351b7021980558bbRichard Sandiford LogicOp() : RegSize(0), ImmLSB(0), ImmSize(0) {} 430b3f912b510f8040690864126351b7021980558bbRichard Sandiford LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize) 431b3f912b510f8040690864126351b7021980558bbRichard Sandiford : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {} 432b3f912b510f8040690864126351b7021980558bbRichard Sandiford 433b3f912b510f8040690864126351b7021980558bbRichard Sandiford operator bool() const { return RegSize; } 434b3f912b510f8040690864126351b7021980558bbRichard Sandiford 435b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned RegSize, ImmLSB, ImmSize; 436b3f912b510f8040690864126351b7021980558bbRichard Sandiford }; 437b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 438b3f912b510f8040690864126351b7021980558bbRichard Sandiford 439b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic LogicOp interpretAndImmediate(unsigned Opcode) { 440b3f912b510f8040690864126351b7021980558bbRichard Sandiford switch (Opcode) { 441b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILL32: return LogicOp(32, 0, 16); 442b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILH32: return LogicOp(32, 16, 16); 443b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILL: return LogicOp(64, 0, 16); 444b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILH: return LogicOp(64, 16, 16); 445b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NIHL: return LogicOp(64, 32, 16); 446b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NIHH: return LogicOp(64, 48, 16); 447b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILF32: return LogicOp(32, 0, 32); 448b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NILF: return LogicOp(64, 0, 32); 449b3f912b510f8040690864126351b7021980558bbRichard Sandiford case SystemZ::NIHF: return LogicOp(64, 32, 32); 450b3f912b510f8040690864126351b7021980558bbRichard Sandiford default: return LogicOp(); 451b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 452b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 453b3f912b510f8040690864126351b7021980558bbRichard Sandiford 454b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Used to return from convertToThreeAddress after replacing two-address 455b3f912b510f8040690864126351b7021980558bbRichard Sandiford// instruction OldMI with three-address instruction NewMI. 456b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic MachineInstr *finishConvertToThreeAddress(MachineInstr *OldMI, 457b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineInstr *NewMI, 458b3f912b510f8040690864126351b7021980558bbRichard Sandiford LiveVariables *LV) { 459b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (LV) { 460b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned NumOps = OldMI->getNumOperands(); 461b3f912b510f8040690864126351b7021980558bbRichard Sandiford for (unsigned I = 1; I < NumOps; ++I) { 462b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineOperand &Op = OldMI->getOperand(I); 463b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Op.isReg() && Op.isKill()) 464b3f912b510f8040690864126351b7021980558bbRichard Sandiford LV->replaceKillInstruction(Op.getReg(), OldMI, NewMI); 465b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 466b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 467b3f912b510f8040690864126351b7021980558bbRichard Sandiford return NewMI; 468b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 469b3f912b510f8040690864126351b7021980558bbRichard Sandiford 4701ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 47193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard SandifordSystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 47293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineBasicBlock::iterator &MBBI, 47393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford LiveVariables *LV) const { 47493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineInstr *MI = MBBI; 47593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineBasicBlock *MBB = MI->getParent(); 47693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 47793c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford unsigned Opcode = MI->getOpcode(); 47893c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford unsigned NumOps = MI->getNumOperands(); 47993c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 48093c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Try to convert something like SLL into SLLK, if supported. 48193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // We prefer to keep the two-operand form where possible both 48293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // because it tends to be shorter and because some instructions 48393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // have memory forms that can be used during spilling. 48493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford if (TM.getSubtargetImpl()->hasDistinctOps()) { 48593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); 48693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford if (ThreeOperandOpcode >= 0) { 487b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineOperand &Dest = MI->getOperand(0); 48893c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineOperand &Src = MI->getOperand(1); 489b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineInstrBuilder MIB = 490b3f912b510f8040690864126351b7021980558bbRichard Sandiford BuildMI(*MBB, MBBI, MI->getDebugLoc(), get(ThreeOperandOpcode)) 491b3f912b510f8040690864126351b7021980558bbRichard Sandiford .addOperand(Dest); 49293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Keep the kill state, but drop the tied flag. 493b3f912b510f8040690864126351b7021980558bbRichard Sandiford MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()); 49493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Keep the remaining operands as-is. 49593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford for (unsigned I = 2; I < NumOps; ++I) 49693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MIB.addOperand(MI->getOperand(I)); 497b3f912b510f8040690864126351b7021980558bbRichard Sandiford return finishConvertToThreeAddress(MI, MIB, LV); 498b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 499b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 500b3f912b510f8040690864126351b7021980558bbRichard Sandiford 501b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Try to convert an AND into an RISBG-type instruction. 502b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (LogicOp And = interpretAndImmediate(Opcode)) { 503b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned NewOpcode; 504b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (And.RegSize == 64) 505b3f912b510f8040690864126351b7021980558bbRichard Sandiford NewOpcode = SystemZ::RISBG; 506b3f912b510f8040690864126351b7021980558bbRichard Sandiford else if (TM.getSubtargetImpl()->hasHighWord()) 507b3f912b510f8040690864126351b7021980558bbRichard Sandiford NewOpcode = SystemZ::RISBLG32; 508b3f912b510f8040690864126351b7021980558bbRichard Sandiford else 509b3f912b510f8040690864126351b7021980558bbRichard Sandiford // We can't use RISBG for 32-bit operations because it clobbers the 510b3f912b510f8040690864126351b7021980558bbRichard Sandiford // high word of the destination too. 511b3f912b510f8040690864126351b7021980558bbRichard Sandiford NewOpcode = 0; 512b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (NewOpcode) { 513b3f912b510f8040690864126351b7021980558bbRichard Sandiford uint64_t Imm = MI->getOperand(2).getImm() << And.ImmLSB; 514b3f912b510f8040690864126351b7021980558bbRichard Sandiford // AND IMMEDIATE leaves the other bits of the register unchanged. 515b3f912b510f8040690864126351b7021980558bbRichard Sandiford Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB); 516b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned Start, End; 517b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (isRxSBGMask(Imm, And.RegSize, Start, End)) { 518b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (NewOpcode == SystemZ::RISBLG32) { 519b3f912b510f8040690864126351b7021980558bbRichard Sandiford Start &= 31; 520b3f912b510f8040690864126351b7021980558bbRichard Sandiford End &= 31; 52193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 522b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineOperand &Dest = MI->getOperand(0); 523b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineOperand &Src = MI->getOperand(1); 524b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineInstrBuilder MIB = 525b3f912b510f8040690864126351b7021980558bbRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), get(NewOpcode)) 526b3f912b510f8040690864126351b7021980558bbRichard Sandiford .addOperand(Dest).addReg(0) 527b3f912b510f8040690864126351b7021980558bbRichard Sandiford .addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()) 528b3f912b510f8040690864126351b7021980558bbRichard Sandiford .addImm(Start).addImm(End + 128).addImm(0); 529b3f912b510f8040690864126351b7021980558bbRichard Sandiford return finishConvertToThreeAddress(MI, MIB, LV); 53093c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 53193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 53293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 53393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford return 0; 53493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford} 53593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 53693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard SandifordMachineInstr * 5371ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 5381ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr *MI, 5391ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 5401ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford int FrameIndex) const { 5411ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MachineFrameInfo *MFI = MF.getFrameInfo(); 5421ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Size = MFI->getObjectSize(FrameIndex); 5431ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 5441ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Eary exit for cases we don't care about 5451ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (Ops.size() != 1) 5461ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 5471ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 5481ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned OpNum = Ops[0]; 549985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi assert(Size == MF.getRegInfo() 550985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi .getRegClass(MI->getOperand(OpNum).getReg())->getSize() && 55124dd7dbe7f2a3338a20314b3863f6b738cc1c298Benjamin Kramer "Invalid size combination"); 5521ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 5536cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned Opcode = MI->getOpcode(); 5546cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) { 5556cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op0IsGPR = (Opcode == SystemZ::LGDR); 5566cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op1IsGPR = (Opcode == SystemZ::LDGR); 5576cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the destination of an LDGR or LGDR, store the 5586cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // source register instead. 5596cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 0) { 5606cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD; 5616cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(StoreOpcode)) 5626cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addOperand(MI->getOperand(1)).addFrameIndex(FrameIndex) 5636cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addImm(0).addReg(0); 5646cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 5656cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the source of an LDGR or LGDR, load the 5666cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // destination register instead. 5676cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 1) { 5686cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD; 5696cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned Dest = MI->getOperand(0).getReg(); 5706cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(LoadOpcode), Dest) 5716cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addReg(0); 5726cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 5736cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 5746cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford 5751ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Look for cases where the source of a simple store or the destination 5761ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // of a simple load is being spilled. Try to use MVC instead. 5771ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // 5781ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Although MVC is in practice a fast choice in these cases, it is still 5791ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // logically a bytewise copy. This means that we cannot use it if the 5801ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // load or store is volatile. It also means that the transformation is 5811ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // not valid in cases where the two memories partially overlap; however, 5821ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // that is not a problem here, because we know that one of the memories 5831ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // is a full frame index. 5841ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (OpNum == 0 && MI->hasOneMemOperand()) { 5851ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineMemOperand *MMO = *MI->memoperands_begin(); 5861ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (MMO->getSize() == Size && !MMO->isVolatile()) { 5871ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of loads. 588cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXLoad)) { 5891ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 590e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addImm(Size) 5911ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 592e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 5931ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 5941ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of stores. 595cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXStore)) { 5961ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 5971ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 598e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addImm(Size).addFrameIndex(FrameIndex).addImm(0) 599e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 6001ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 6011ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 6021ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 6031ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 604fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // If the spilled operand is the final one, try to change <INSN>R 605fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // into <INSN>. 6066cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford int MemOpcode = SystemZ::getMemOpcode(Opcode); 607fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemOpcode >= 0) { 608fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford unsigned NumOps = MI->getNumExplicitOperands(); 609fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (OpNum == NumOps - 1) { 610fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford const MCInstrDesc &MemDesc = get(MemOpcode); 611fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t AccessBytes = SystemZII::getAccessSize(MemDesc.TSFlags); 612fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes != 0 && "Size of access should be known"); 613fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes <= Size && "Access outside the frame index"); 614fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t Offset = Size - AccessBytes; 615fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(MemOpcode)); 616fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford for (unsigned I = 0; I < OpNum; ++I) 617fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addOperand(MI->getOperand(I)); 618fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addFrameIndex(FrameIndex).addImm(Offset); 619fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemDesc.TSFlags & SystemZII::HasIndex) 620fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addReg(0); 621fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford return MIB; 622fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 623fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 624fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford 6251ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 6261ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 6271ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 6281ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 6291ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, 6301ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 6311ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr* LoadMI) const { 6321ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return 0; 6331ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 6341ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 6351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool 6361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 6371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 6381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::L128: 6391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LG); 6401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ST128: 6431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STG); 6441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::LX: 6471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LD); 6481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::STX: 6511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STD); 6521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJDYNALLOC: 6551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitAdjDynAlloc(MI); 6561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 6591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 6601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 66344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiforduint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { 66444b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford if (MI->getOpcode() == TargetOpcode::INLINEASM) { 66544b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const MachineFunction *MF = MI->getParent()->getParent(); 66644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const char *AsmStr = MI->getOperand(0).getSymbolName(); 66744b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 66844b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford } 66944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return MI->getDesc().getSize(); 67044b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford} 67144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford 67206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZII::Branch 67306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { 6741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 6751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BR: 6761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::J: 6771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::JG: 678d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, 6796824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford SystemZ::CCMASK_ANY, &MI->getOperand(0)); 6801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRC: 6821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRCL: 683d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, 6846824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(0).getImm(), 6856824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(1).getImm(), &MI->getOperand(2)); 686d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 6872d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CIJ: 688d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CRJ: 6896824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return SystemZII::Branch(SystemZII::BranchC, SystemZ::CCMASK_ICMP, 6906824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 691d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 6922d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGIJ: 693d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGRJ: 6946824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return SystemZII::Branch(SystemZII::BranchCG, SystemZ::CCMASK_ICMP, 6956824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 6961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 69806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford llvm_unreachable("Unrecognized branch opcode"); 6991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 7011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 7031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &LoadOpcode, 7041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &StoreOpcode) const { 7051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 7061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L; 7071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST32; 7081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR64BitRegClass || 7091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR64BitRegClass) { 7101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LG; 7111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STG; 7121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR128BitRegClass || 7131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR128BitRegClass) { 7141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L128; 7151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST128; 7161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP32BitRegClass) { 7171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LE; 7181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STE; 7191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP64BitRegClass) { 7201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LD; 7211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STD; 7221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP128BitRegClass) { 7231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LX; 7241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STX; 7251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 7261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported regclass to load or store"); 7271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 7281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 7301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset) const { 7311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = get(Opcode); 7321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 7331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 7341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for unsigned 12-bit displacements. 7351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 7361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp12Opcode >= 0) 7371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp12Opcode; 7381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // All address-related instructions can use unsigned 12-bit 7401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacements. 7411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 7421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(Offset) && isInt<20>(Offset2)) { 7441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for signed 20-bit displacements. 7451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 7461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp20Opcode >= 0) 7471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp20Opcode; 7481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether Opcode allows signed 20-bit displacements. 7501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MCID.TSFlags & SystemZII::Has20BitOffset) 7511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 7521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 7541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 7551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7569b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandifordunsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const { 7579b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford switch (Opcode) { 7589b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::L: return SystemZ::LT; 7599b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LY: return SystemZ::LT; 7609b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LG: return SystemZ::LTG; 7619b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGF: return SystemZ::LTGF; 7629b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LR: return SystemZ::LTR; 7639b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGFR: return SystemZ::LTGFR; 7649b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGR: return SystemZ::LTGR; 7659b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford default: return 0; 7669b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford } 7679b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford} 7689b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford 769b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Return true if Mask matches the regexp 0*1+0*, given that zero masks 770b3f912b510f8040690864126351b7021980558bbRichard Sandiford// have already been filtered out. Store the first set bit in LSB and 771b3f912b510f8040690864126351b7021980558bbRichard Sandiford// the number of set bits in Length if so. 772b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic bool isStringOfOnes(uint64_t Mask, unsigned &LSB, unsigned &Length) { 773b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned First = findFirstSet(Mask); 774b3f912b510f8040690864126351b7021980558bbRichard Sandiford uint64_t Top = (Mask >> First) + 1; 775b3f912b510f8040690864126351b7021980558bbRichard Sandiford if ((Top & -Top) == Top) { 776b3f912b510f8040690864126351b7021980558bbRichard Sandiford LSB = First; 777b3f912b510f8040690864126351b7021980558bbRichard Sandiford Length = findFirstSet(Top); 778b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 779b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 780b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 781b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 782b3f912b510f8040690864126351b7021980558bbRichard Sandiford 783b3f912b510f8040690864126351b7021980558bbRichard Sandifordbool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize, 784b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned &Start, unsigned &End) const { 785b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Reject trivial all-zero masks. 786b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Mask == 0) 787b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 788b3f912b510f8040690864126351b7021980558bbRichard Sandiford 789b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Handle the 1+0+ or 0+1+0* cases. Start then specifies the index of 790b3f912b510f8040690864126351b7021980558bbRichard Sandiford // the msb and End specifies the index of the lsb. 791b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned LSB, Length; 792b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (isStringOfOnes(Mask, LSB, Length)) { 793b3f912b510f8040690864126351b7021980558bbRichard Sandiford Start = 63 - (LSB + Length - 1); 794b3f912b510f8040690864126351b7021980558bbRichard Sandiford End = 63 - LSB; 795b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 796b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 797b3f912b510f8040690864126351b7021980558bbRichard Sandiford 798b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Handle the wrap-around 1+0+1+ cases. Start then specifies the msb 799b3f912b510f8040690864126351b7021980558bbRichard Sandiford // of the low 1s and End specifies the lsb of the high 1s. 800b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (isStringOfOnes(Mask ^ allOnes(BitSize), LSB, Length)) { 801b3f912b510f8040690864126351b7021980558bbRichard Sandiford assert(LSB > 0 && "Bottom bit must be set"); 802b3f912b510f8040690864126351b7021980558bbRichard Sandiford assert(LSB + Length < BitSize && "Top bit must be set"); 803b3f912b510f8040690864126351b7021980558bbRichard Sandiford Start = 63 - (LSB - 1); 804b3f912b510f8040690864126351b7021980558bbRichard Sandiford End = 63 - (LSB + Length); 805b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 806b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 807b3f912b510f8040690864126351b7021980558bbRichard Sandiford 808b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 809b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 810b3f912b510f8040690864126351b7021980558bbRichard Sandiford 8112d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandifordunsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, 8122d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford const MachineInstr *MI) const { 813d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford switch (Opcode) { 814d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CR: 815d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CRJ; 816d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGR: 817d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CGRJ; 8182d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CHI: 8192d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; 8202d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGHI: 8212d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; 822d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford default: 823d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return 0; 824d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford } 825d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford} 826d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 8271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 8281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 8291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg, uint64_t Value) const { 8301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 8311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 8321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(Value)) 8331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGHI; 8341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLL(Value)) 8351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILL; 8361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLH(Value)) { 8371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILH; 8381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value >>= 16; 8391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 8401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(isInt<32>(Value) && "Huge values not handled yet"); 8411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGFI; 8421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 8441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 845