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