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