AArch64InstrInfo.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
172062f5744557e270a38192554c3126ea5f97434Tim Northover//===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
972062f5744557e270a38192554c3126ea5f97434Tim Northover//
1072062f5744557e270a38192554c3126ea5f97434Tim Northover// This file contains the AArch64 implementation of the TargetInstrInfo class.
1172062f5744557e270a38192554c3126ea5f97434Tim Northover//
1272062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
1372062f5744557e270a38192554c3126ea5f97434Tim Northover
1472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64InstrInfo.h"
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64Subtarget.h"
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "MCTargetDesc/AArch64AddressingModes.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFrameInfo.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineInstrBuilder.h"
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/CodeGen/MachineMemOperand.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineRegisterInfo.h"
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/CodeGen/PseudoSourceValue.h"
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCInst.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm;
2772062f5744557e270a38192554c3126ea5f97434Tim Northover
28354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka#define GET_INSTRINFO_CTOR_DTOR
2972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenInstrInfo.inc"
3072062f5744557e270a38192554c3126ea5f97434Tim Northover
3172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI)
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP),
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RI(this, &STI), Subtarget(STI) {}
3472062f5744557e270a38192554c3126ea5f97434Tim Northover
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// GetInstSize - Return the number of bytes of code the specified
36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// instruction may be.  This returns the maximum number of bytes.
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCInstrDesc &Desc = MI->getDesc();
3972062f5744557e270a38192554c3126ea5f97434Tim Northover
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Desc.getOpcode()) {
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Anything not explicitly designated otherwise is a nomal 4-byte insn.
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 4;
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::DBG_VALUE:
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::EH_LABEL:
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::IMPLICIT_DEF:
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::KILL:
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
4972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
5072062f5744557e270a38192554c3126ea5f97434Tim Northover
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("GetInstSizeInBytes()- Unable to determin insn size");
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            SmallVectorImpl<MachineOperand> &Cond) {
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Block ends with fall-through condbranch.
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (LastInst->getOpcode()) {
5872062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unknown branch instruction?");
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::Bcc:
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(1).getMBB();
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBZW:
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBZX:
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBNZW:
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBNZX:
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(1).getMBB();
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(-1));
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBZW:
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBZX:
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBNZW:
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBNZX:
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(2).getMBB();
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(-1));
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(1));
8272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
8372062f5744557e270a38192554c3126ea5f97434Tim Northover}
8472062f5744557e270a38192554c3126ea5f97434Tim Northover
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Branch analysis.
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock *&TBB,
88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock *&FBB,
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   SmallVectorImpl<MachineOperand> &Cond,
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   bool AllowModify) const {
9172062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block has no terminators, it just falls into the block after it.
9272062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
9372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin())
9472062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
9572062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
9672062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
9772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
9872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
9972062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
10072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
10172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!isUnpredicatedTerminator(I))
10272062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
10372062f5744557e270a38192554c3126ea5f97434Tim Northover
10472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the last instruction in the block.
10572062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *LastInst = I;
10672062f5744557e270a38192554c3126ea5f97434Tim Northover
10772062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there is only one terminator instruction, process it.
10872062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned LastOpc = LastInst->getOpcode();
10972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isUncondBranchOpcode(LastOpc)) {
11172062f5744557e270a38192554c3126ea5f97434Tim Northover      TBB = LastInst->getOperand(0).getMBB();
11272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
11372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isCondBranchOpcode(LastOpc)) {
115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Block ends with fall-through condbranch.
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      parseCondBranch(LastInst, TBB, Cond);
11772062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
11872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true; // Can't handle indirect branch.
12072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12172062f5744557e270a38192554c3126ea5f97434Tim Northover
12272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the instruction before it if it is a terminator.
12372062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *SecondLastInst = I;
12472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SecondLastOpc = SecondLastInst->getOpcode();
12572062f5744557e270a38192554c3126ea5f97434Tim Northover
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  // If AllowModify is true and the block ends with two or more unconditional
12772062f5744557e270a38192554c3126ea5f97434Tim Northover  // branches, delete all but the first unconditional branch.
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AllowModify && isUncondBranchOpcode(LastOpc)) {
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    while (isUncondBranchOpcode(SecondLastOpc)) {
13072062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst->eraseFromParent();
13172062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst = SecondLastInst;
13272062f5744557e270a38192554c3126ea5f97434Tim Northover      LastOpc = LastInst->getOpcode();
13372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
13472062f5744557e270a38192554c3126ea5f97434Tim Northover        // Return now the only terminator is an unconditional branch.
13572062f5744557e270a38192554c3126ea5f97434Tim Northover        TBB = LastInst->getOperand(0).getMBB();
13672062f5744557e270a38192554c3126ea5f97434Tim Northover        return false;
13772062f5744557e270a38192554c3126ea5f97434Tim Northover      } else {
13872062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastInst = I;
13972062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastOpc = SecondLastInst->getOpcode();
14072062f5744557e270a38192554c3126ea5f97434Tim Northover      }
14172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
14272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14372062f5744557e270a38192554c3126ea5f97434Tim Northover
14472062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there are three terminators, we don't know what sort of block this is.
14572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
14672062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
14772062f5744557e270a38192554c3126ea5f97434Tim Northover
14872062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with a B and a Bcc, handle it.
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    parseCondBranch(SecondLastInst, TBB, Cond);
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    FBB = LastInst->getOperand(0).getMBB();
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
15372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
15472062f5744557e270a38192554c3126ea5f97434Tim Northover
15572062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with two unconditional branches, handle it.  The second
15672062f5744557e270a38192554c3126ea5f97434Tim Northover  // one is not executed, so remove it.
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
15872062f5744557e270a38192554c3126ea5f97434Tim Northover    TBB = SecondLastInst->getOperand(0).getMBB();
15972062f5744557e270a38192554c3126ea5f97434Tim Northover    I = LastInst;
16072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (AllowModify)
16172062f5744557e270a38192554c3126ea5f97434Tim Northover      I->eraseFromParent();
16272062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
16372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
16472062f5744557e270a38192554c3126ea5f97434Tim Northover
165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // ...likewise if it ends with an indirect branch followed by an unconditional
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // branch.
167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    I = LastInst;
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AllowModify)
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      I->eraseFromParent();
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
17472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise, can't handle this.
17572062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
17672062f5744557e270a38192554c3126ea5f97434Tim Northover}
17772062f5744557e270a38192554c3126ea5f97434Tim Northover
17872062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64InstrInfo::ReverseBranchCondition(
179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVectorImpl<MachineOperand> &Cond) const {
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cond[0].getImm() != -1) {
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Regular Bcc
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64CC::CondCode CC = (AArch64CC::CondCode)(int)Cond[0].getImm();
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond[0].setImm(AArch64CC::getInvertedCondCode(CC));
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Folded compare-and-branch
186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown conditional branch!");
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZW:
190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBNZW);
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZW:
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBZW);
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZX:
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBNZX);
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZX:
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBZX);
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZW:
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBNZW);
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZW:
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBZW);
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZX:
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBNZX);
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZX:
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBZX);
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
21472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
21572062f5744557e270a38192554c3126ea5f97434Tim Northover
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
21772062f5744557e270a38192554c3126ea5f97434Tim Northover}
21872062f5744557e270a38192554c3126ea5f97434Tim Northover
21972062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
22072062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == MBB.begin())
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
22372062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
22472062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
22572062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
22672062f5744557e270a38192554c3126ea5f97434Tim Northover      return 0;
22772062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
22872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!isUncondBranchOpcode(I->getOpcode()) &&
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      !isCondBranchOpcode(I->getOpcode()))
23172062f5744557e270a38192554c3126ea5f97434Tim Northover    return 0;
23272062f5744557e270a38192554c3126ea5f97434Tim Northover
23372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
23472062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
23572062f5744557e270a38192554c3126ea5f97434Tim Northover
23672062f5744557e270a38192554c3126ea5f97434Tim Northover  I = MBB.end();
23772062f5744557e270a38192554c3126ea5f97434Tim Northover
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == MBB.begin())
239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 1;
24072062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!isCondBranchOpcode(I->getOpcode()))
24272062f5744557e270a38192554c3126ea5f97434Tim Northover    return 1;
24372062f5744557e270a38192554c3126ea5f97434Tim Northover
24472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
24572062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
24672062f5744557e270a38192554c3126ea5f97434Tim Northover  return 2;
24772062f5744557e270a38192554c3126ea5f97434Tim Northover}
24872062f5744557e270a38192554c3126ea5f97434Tim Northover
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::instantiateCondBranch(
250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, DebugLoc DL, MachineBasicBlock *TBB,
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const SmallVectorImpl<MachineOperand> &Cond) const {
252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cond[0].getImm() != -1) {
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Regular Bcc
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(&MBB, DL, get(AArch64::Bcc)).addImm(Cond[0].getImm()).addMBB(TBB);
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Folded compare-and-branch
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstrBuilder MIB =
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(&MBB, DL, get(Cond[1].getImm())).addReg(Cond[2].getReg());
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond.size() > 3)
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MIB.addImm(Cond[3].getImm());
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MIB.addMBB(TBB);
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
26472062f5744557e270a38192554c3126ea5f97434Tim Northover
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::InsertBranch(
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const {
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Shouldn't be a fall through.
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!FBB) {
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond.empty()) // Unconditional branch?
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB);
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      instantiateCondBranch(MBB, DL, TBB, Cond);
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 1;
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Two-way conditional branch.
280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  instantiateCondBranch(MBB, DL, TBB, Cond);
281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB);
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 2;
283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Find the original register that VReg is copied from.
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg) {
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (TargetRegisterInfo::isVirtualRegister(VReg)) {
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr *DefMI = MRI.getVRegDef(VReg);
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!DefMI->isFullCopy())
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return VReg;
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VReg = DefMI->getOperand(1).getReg();
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return VReg;
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Determine if VReg is defined by an instruction that can be folded into a
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// csel instruction. If so, return the folded opcode, and the replacement
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// register.
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg,
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                unsigned *NewVReg = nullptr) {
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  VReg = removeCopies(MRI, VReg);
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!TargetRegisterInfo::isVirtualRegister(VReg))
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.getRegClass(VReg));
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstr *DefMI = MRI.getVRegDef(VReg);
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned SrcOpNum = 0;
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (DefMI->getOpcode()) {
310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // if NZCV is used, do not fold.
313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1)
314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // fall-through to ADDXri and ADDWri.
316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri:
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWri:
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // add x, 1 -> csinc.
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!DefMI->getOperand(2).isImm() || DefMI->getOperand(2).getImm() != 1 ||
320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        DefMI->getOperand(3).getImm() != 0)
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 1;
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr;
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNXrr:
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNWrr: {
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // not x -> csinv, represented as orn dst, xzr, src.
329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg());
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 2;
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr;
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // if NZCV is used, do not fold.
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1)
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // fall-through to SUBXrr and SUBWrr.
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrr:
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrr: {
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // neg x -> csneg, represented as sub dst, xzr, src.
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg());
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 2;
350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr;
351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
35372062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && SrcOpNum && "Missing parameters");
357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NewVReg)
359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *NewVReg = DefMI->getOperand(SrcOpNum).getReg();
360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Opc;
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::canInsertSelect(
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineBasicBlock &MBB, const SmallVectorImpl<MachineOperand> &Cond,
365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned TrueReg, unsigned FalseReg, int &CondCycles, int &TrueCycles,
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int &FalseCycles) const {
367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check register classes.
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterClass *RC =
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!RC)
37272062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Expanding cbz/tbz requires an extra cycle of latency on the condition.
375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ExtraCondLat = Cond.size() != 1;
376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // GPRs are handled by csel.
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Fold in x+1, -x, and ~x when applicable.
379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64allRegClass.hasSubClassEq(RC) ||
380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Single-cycle csel, csinc, csinv, and csneg.
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CondCycles = 1 + ExtraCondLat;
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TrueCycles = FalseCycles = 1;
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (canFoldIntoCSel(MRI, TrueReg))
385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TrueCycles = 0;
386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (canFoldIntoCSel(MRI, FalseReg))
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FalseCycles = 0;
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
38972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39072062f5744557e270a38192554c3126ea5f97434Tim Northover
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Scalar floating point is handled by fcsel.
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Form fabs, fmin, and fmax when applicable.
393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.hasSubClassEq(RC) ||
394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.hasSubClassEq(RC)) {
395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CondCycles = 5 + ExtraCondLat;
396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TrueCycles = FalseCycles = 2;
397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Can't do vectors.
40172062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
40272062f5744557e270a38192554c3126ea5f97434Tim Northover}
40372062f5744557e270a38192554c3126ea5f97434Tim Northover
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    MachineBasicBlock::iterator I, DebugLoc DL,
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned DstReg,
407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    const SmallVectorImpl<MachineOperand> &Cond,
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned TrueReg, unsigned FalseReg) const {
409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Parse the condition code, see parseCondBranch() above.
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode CC;
413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Cond.size()) {
414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unknown condition opcode in Cond");
416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1: // b.cc
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CC = AArch64CC::CondCode(Cond[0].getImm());
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 3: { // cbz/cbnz
420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We must insert a compare against 0.
421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Is64Bit;
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
42372062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown branch opcode in Cond");
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZW:
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 0;
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZX:
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 1;
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZW:
434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 0;
435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZX:
438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 1;
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SrcReg = Cond[2].getReg();
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Is64Bit) {
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // cmp reg, #0 is actually subs xzr, reg, #0.
445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.constrainRegClass(SrcReg, &AArch64::GPR64spRegClass);
446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::SUBSXri), AArch64::XZR)
447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0);
450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.constrainRegClass(SrcReg, &AArch64::GPR32spRegClass);
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::SUBSWri), AArch64::WZR)
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0);
456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4: { // tbz/tbnz
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We must insert a tst instruction.
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
46272062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown branch opcode in Cond");
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZW:
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZX:
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZW:
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZX:
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // cmp reg, #foo is actually ands xzr, reg, #1<<foo.
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW)
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ANDSWri), AArch64::WZR)
476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(Cond[2].getReg())
477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32));
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ANDSXri), AArch64::XZR)
481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(Cond[2].getReg())
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64));
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterClass *RC = nullptr;
490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool TryFold = false;
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MRI.constrainRegClass(DstReg, &AArch64::GPR64RegClass)) {
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR64RegClass;
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::CSELXr;
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TryFold = true;
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::GPR32RegClass)) {
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR32RegClass;
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::CSELWr;
498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TryFold = true;
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR64RegClass)) {
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::FPR64RegClass;
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::FCSELDrrr;
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR32RegClass)) {
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::FPR32RegClass;
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::FCSELSrrr;
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(RC && "Unsupported regclass");
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Try folding simple instructions into the csel.
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TryFold) {
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned NewVReg = 0;
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned FoldedOpc = canFoldIntoCSel(MRI, TrueReg, &NewVReg);
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (FoldedOpc) {
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The folded opcodes csinc, csinc and csneg apply the operation to
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // FalseReg, so we need to invert the condition.
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::getInvertedCondCode(CC);
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TrueReg = FalseReg;
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FoldedOpc = canFoldIntoCSel(MRI, FalseReg, &NewVReg);
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Fold the operation. Leave any dead instructions for DCE to clean up.
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (FoldedOpc) {
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FalseReg = NewVReg;
523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = FoldedOpc;
524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The extends the live range of NewVReg.
525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.clearKillFlags(NewVReg);
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
52772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
52872062f5744557e270a38192554c3126ea5f97434Tim Northover
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Pull all virtual register into the appropriate class.
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(TrueReg, RC);
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(FalseReg, RC);
53272062f5744557e270a38192554c3126ea5f97434Tim Northover
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Insert the csel.
534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(MBB, I, DL, get(Opc), DstReg).addReg(TrueReg).addReg(FalseReg).addImm(
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC);
53672062f5744557e270a38192554c3126ea5f97434Tim Northover}
53772062f5744557e270a38192554c3126ea5f97434Tim Northover
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             unsigned &SrcReg, unsigned &DstReg,
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             unsigned &SubIdx) const {
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI.getOpcode()) {
542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBFMXri: // aka sxtw
545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::UBFMXri: // aka uxtw
546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check for the 32 -> 64 bit extension case, these instructions can do
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // much more.
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI.getOperand(2).getImm() != 0 || MI.getOperand(3).getImm() != 31)
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This is a signed or unsigned 32 -> 64 bit extension.
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI.getOperand(1).getReg();
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DstReg = MI.getOperand(0).getReg();
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SubIdx = AArch64::sub_32;
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// analyzeCompare - For a comparison instruction, return the source registers
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if the comparison instruction can be analyzed.
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      unsigned &SrcReg2, int &CmpMask,
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      int &CmpValue) const {
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrs:
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrx:
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrs:
572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx:
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrr:
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrs:
575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrx:
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrr:
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrs:
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx:
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Replace SUBSWrr with SUBWrr if NZCV is not used.
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = MI->getOperand(2).getReg();
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = 0;
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = 0;
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = MI->getOperand(2).getImm();
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWri:
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXri:
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // ANDS does not use the same encoding scheme as the others xxxS
597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // instructions.
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = 0;
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = AArch64_AM::decodeLogicalImmediate(
602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).getImm(),
603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOpcode() == AArch64::ANDSWri ? 32 : 64);
604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool UpdateOperandRegClass(MachineInstr *Instr) {
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineBasicBlock *MBB = Instr->getParent();
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MBB && "Can't get MachineBasicBlock here");
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction *MF = MBB->getParent();
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MF && "Can't get MachineFunction here");
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetMachine *TM = &MF->getTarget();
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetInstrInfo *TII = TM->getInstrInfo();
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = TM->getRegisterInfo();
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineRegisterInfo *MRI = &MF->getRegInfo();
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned OpIdx = 0, EndIdx = Instr->getNumOperands(); OpIdx < EndIdx;
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       ++OpIdx) {
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineOperand &MO = Instr->getOperand(OpIdx);
623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterClass *OpRegCstraints =
624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Instr->getRegClassConstraint(OpIdx, TII, TRI);
625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If there's no constraint, there's nothing to do.
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!OpRegCstraints)
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If the operand is a frame index, there's nothing to do here.
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A frame index operand will resolve correctly during PEI.
631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MO.isFI())
632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MO.isReg() &&
635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Operand has register constraints without being a register!");
636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Reg = MO.getReg();
638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!OpRegCstraints->contains(Reg))
640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!OpRegCstraints->hasSubClassEq(MRI->getRegClass(Reg)) &&
642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               !MRI->constrainRegClass(Reg, OpRegCstraints))
643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
64472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
64572062f5744557e270a38192554c3126ea5f97434Tim Northover
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
64772062f5744557e270a38192554c3126ea5f97434Tim Northover}
64872062f5744557e270a38192554c3126ea5f97434Tim Northover
649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// optimizeCompareInstr - Convert the instruction supplying the argument to the
650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// comparison into one that sets the zero bit in the flags register.
651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::optimizeCompareInstr(
652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int CmpValue, const MachineRegisterInfo *MRI) const {
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Replace SUBSWrr with SUBWrr if NZCV is not used.
656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Cmp_NZCV = CmpInstr->findRegisterDefOperandIdx(AArch64::NZCV, true);
657dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cmp_NZCV != -1) {
658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned NewOpc;
659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (CmpInstr->getOpcode()) {
660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrr:      NewOpc = AArch64::ADDWrr; break;
663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWri:      NewOpc = AArch64::ADDWri; break;
664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrs:      NewOpc = AArch64::ADDWrs; break;
665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrx:      NewOpc = AArch64::ADDWrx; break;
666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrr:      NewOpc = AArch64::ADDXrr; break;
667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXri:      NewOpc = AArch64::ADDXri; break;
668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrs:      NewOpc = AArch64::ADDXrs; break;
669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrx:      NewOpc = AArch64::ADDXrx; break;
670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrr:      NewOpc = AArch64::SUBWrr; break;
671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWri:      NewOpc = AArch64::SUBWri; break;
672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrs:      NewOpc = AArch64::SUBWrs; break;
673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrx:      NewOpc = AArch64::SUBWrx; break;
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrr:      NewOpc = AArch64::SUBXrr; break;
675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXri:      NewOpc = AArch64::SUBXri; break;
676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrs:      NewOpc = AArch64::SUBXrs; break;
677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrx:      NewOpc = AArch64::SUBXrx; break;
678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCInstrDesc &MCID = get(NewOpc);
681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpInstr->setDesc(MCID);
682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpInstr->RemoveOperand(Cmp_NZCV);
683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool succeeded = UpdateOperandRegClass(CmpInstr);
684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    (void)succeeded;
685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(succeeded && "Some operands reg class are incompatible!");
686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Continue only if we have a "ri" where immediate is zero.
690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CmpValue != 0 || SrcReg2 != 0)
691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // CmpInstr is a Compare instruction if destination register is not used.
694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MRI->use_nodbg_empty(CmpInstr->getOperand(0).getReg()))
695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Get the unique definition of SrcReg.
698dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MI)
700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We iterate backward, starting from the instruction before CmpInstr and
703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // stop when reaching the definition of the source register or done with the
704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // basic block, to check whether NZCV is used or modified in between.
705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineBasicBlock::iterator I = CmpInstr, E = MI,
706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              B = CmpInstr->getParent()->begin();
707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Early exit if CmpInstr is at the beginning of the BB.
709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == B)
710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check whether the definition of SrcReg is in the same basic block as
713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Compare. If not, we can't optimize away the Compare.
714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->getParent() != CmpInstr->getParent())
715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check that NZCV isn't set between the comparison instruction and the one we
718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // want to change.
719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = &getRegisterInfo();
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (--I; I != E; --I) {
721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr &Instr = *I;
72272062f5744557e270a38192554c3126ea5f97434Tim Northover
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Instr.modifiesRegister(AArch64::NZCV, TRI) ||
724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Instr.readsRegister(AArch64::NZCV, TRI))
725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // This instruction modifies or uses NZCV after the one we want to
726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // change. We can't do this transformation.
727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (I == B)
729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The 'and' is below the comparison instruction.
730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NewOpc = MI->getOpcode();
734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrr:
738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrr:
740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrr:    NewOpc = AArch64::ADDSWrr; break;
747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWri:    NewOpc = AArch64::ADDSWri; break;
748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrr:    NewOpc = AArch64::ADDSXrr; break;
749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri:    NewOpc = AArch64::ADDSXri; break;
750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADCWr:     NewOpc = AArch64::ADCSWr; break;
751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADCXr:     NewOpc = AArch64::ADCSXr; break;
752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrr:    NewOpc = AArch64::SUBSWrr; break;
753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWri:    NewOpc = AArch64::SUBSWri; break;
754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrr:    NewOpc = AArch64::SUBSXrr; break;
755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXri:    NewOpc = AArch64::SUBSXri; break;
756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBCWr:     NewOpc = AArch64::SBCSWr; break;
757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBCXr:     NewOpc = AArch64::SBCSXr; break;
758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWri:    NewOpc = AArch64::ANDSWri; break;
759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXri:    NewOpc = AArch64::ANDSXri; break;
760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
76172062f5744557e270a38192554c3126ea5f97434Tim Northover
762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Scan forward for the use of NZCV.
763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // When checking against MI: if it's a conditional code requires
764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // checking of V bit, then this is not safe to do.
765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // It is safe to remove CmpInstr if NZCV is redefined or killed.
766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If we are done with the basic block, we need to check whether NZCV is
767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // live-out.
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsSafe = false;
769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MachineBasicBlock::iterator I = CmpInstr,
770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   E = CmpInstr->getParent()->end();
771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       !IsSafe && ++I != E;) {
772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr &Instr = *I;
773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned IO = 0, EO = Instr.getNumOperands(); !IsSafe && IO != EO;
774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         ++IO) {
775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const MachineOperand &MO = Instr.getOperand(IO);
776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MO.isRegMask() && MO.clobbersPhysReg(AArch64::NZCV)) {
777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IsSafe = true;
778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!MO.isReg() || MO.getReg() != AArch64::NZCV)
781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        continue;
782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MO.isDef()) {
783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IsSafe = true;
784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
78672062f5744557e270a38192554c3126ea5f97434Tim Northover
787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Decode the condition code.
788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned Opc = Instr.getOpcode();
789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64CC::CondCode CC;
790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      switch (Opc) {
791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      default:
792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::Bcc:
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CC = (AArch64CC::CondCode)Instr.getOperand(IO - 2).getImm();
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINVWr:
797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINVXr:
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINCWr:
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINCXr:
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSELWr:
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSELXr:
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSNEGWr:
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSNEGXr:
804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::FCSELSrrr:
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::FCSELDrrr:
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CC = (AArch64CC::CondCode)Instr.getOperand(IO - 1).getImm();
807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // It is not safe to remove Compare instruction if Overflow(V) is used.
811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      switch (CC) {
812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      default:
813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // NZCV can be used multiple times, we should continue.
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::VS:
816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::VC:
817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::GE:
818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::LT:
819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::GT:
820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::LE:
821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
82272062f5744557e270a38192554c3126ea5f97434Tim Northover      }
82372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
82472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
82572062f5744557e270a38192554c3126ea5f97434Tim Northover
826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If NZCV is not killed nor re-defined, we should check whether it is
827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // live-out. If it is live-out, do not optimize.
828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!IsSafe) {
829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock *ParentBlock = CmpInstr->getParent();
830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (auto *MBB : ParentBlock->successors())
831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MBB->isLiveIn(AArch64::NZCV))
832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Update the instruction to set NZCV.
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI->setDesc(get(NewOpc));
837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  CmpInstr->eraseFromParent();
838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool succeeded = UpdateOperandRegClass(MI);
839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  (void)succeeded;
840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(succeeded && "Some operands reg class are incompatible!");
841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI->addRegisterDefined(AArch64::NZCV, TRI);
842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
84372062f5744557e270a38192554c3126ea5f97434Tim Northover}
844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is this instruction has a non-zero immediate
846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::hasShiftedReg(const MachineInstr *MI) const {
847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrs:
851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrs:
852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrs:
853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrs:
854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWrs:
855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXrs:
856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWrs:
857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXrs:
858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICSWrs:
859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICSXrs:
860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICWrs:
861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICXrs:
862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Brr:
863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CBrr:
864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CHrr:
865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CWrr:
866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CXrr:
867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Hrr:
868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Wrr:
869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Xrr:
870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EONWrs:
871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EONXrs:
872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EORWrs:
873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EORXrs:
874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNWrs:
875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNXrs:
876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRWrs:
877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRXrs:
878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrs:
879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrs:
880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrs:
881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrs:
882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(3).isImm()) {
883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned val = MI->getOperand(3).getImm();
884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return (val != 0);
885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
88772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
88972062f5744557e270a38192554c3126ea5f97434Tim Northover}
89072062f5744557e270a38192554c3126ea5f97434Tim Northover
891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is this instruction has a non-zero immediate
892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::hasExtendedReg(const MachineInstr *MI) const {
893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrx:
897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx:
898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx64:
899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrx:
900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrx:
901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrx64:
902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrx:
903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx:
904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx64:
905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrx:
906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrx:
907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrx64:
908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(3).isImm()) {
909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned val = MI->getOperand(3).getImm();
910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return (val != 0);
911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
91485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
91785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply sets its single destination register
919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// to zero. This is equivalent to a register rename of the zero-register.
920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isGPRZero(const MachineInstr *MI) const {
921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::MOVZWi:
925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::MOVZXi: // movz Rd, #0 (LSL #0)
926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) {
927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 3 &&
928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(2).getImm() == 0 && "invalid MOVZi operands");
929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWri: // and Rd, Rzr, #imm
933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::WZR;
934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXri:
935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::XZR;
936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY:
937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::WZR;
938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
94185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply renames a general register without
943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// modifying bits.
944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isGPRCopy(const MachineInstr *MI) const {
945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
94685d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  default:
947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY: {
949dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // GPR32 copies will by lowered to ORRXrs
950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (AArch64::GPR32RegClass.contains(DstReg) ||
952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            AArch64::GPR64RegClass.contains(DstReg));
95385d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRXrs: // orr Xd, Xzr, Xm (LSL #0)
955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).getReg() == AArch64::XZR) {
956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 4 &&
957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(3).getImm() == 0 && "invalid ORRrs operands");
958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri: // add Xd, Xn, #0 (LSL #0)
961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(2).getImm() == 0) {
962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 4 &&
963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(3).getImm() == 0 && "invalid ADDXri operands");
964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
96885d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
96985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply renames a general register without
971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// modifying bits.
972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isFPRCopy(const MachineInstr *MI) const {
973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY: {
977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FPR64 copies will by lowered to ORR.16b
978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (AArch64::FPR64RegClass.contains(DstReg) ||
980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            AArch64::FPR128RegClass.contains(DstReg));
98185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRv16i8:
983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 3 && MI->getOperand(0).isReg() &&
985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "invalid ORRv16i8 operands");
986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
99085d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
99185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               int &FrameIndex) const {
994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBui:
1000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHui:
1001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() &&
1005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) {
1006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FrameIndex = MI->getOperand(1).getIndex();
1007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MI->getOperand(0).getReg();
1008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
101172062f5744557e270a38192554c3126ea5f97434Tim Northover
1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 0;
101372062f5744557e270a38192554c3126ea5f97434Tim Northover}
101472062f5744557e270a38192554c3126ea5f97434Tim Northover
1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              int &FrameIndex) const {
1017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBui:
1023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHui:
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() &&
1028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) {
1029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FrameIndex = MI->getOperand(1).getIndex();
1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MI->getOperand(0).getReg();
1031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
103372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 0;
1035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
103672062f5744557e270a38192554c3126ea5f97434Tim Northover
1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is load/store scales or extends its register offset.
1038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// This refers to scaling a dynamic index as opposed to scaled immediates.
1039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// MI should be a memory op that allows scaled addressing.
1040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isScaledAddr(const MachineInstr *MI) const {
1041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBroW:
1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBroW:
1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDroW:
1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHroW:
1048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHroW:
1049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQroW:
1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWroW:
1051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXroW:
1052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWroW:
1053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXroW:
1054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWroW:
1055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSroW:
1056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWroW:
1057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXroW:
1058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBroW:
1059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBroW:
1060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDroW:
1061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHroW:
1062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHroW:
1063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQroW:
1064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSroW:
1065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWroW:
1066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXroW:
1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBroX:
1068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBroX:
1069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDroX:
1070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHroX:
1071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHroX:
1072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQroX:
1073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWroX:
1074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXroX:
1075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWroX:
1076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXroX:
1077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWroX:
1078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSroX:
1079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWroX:
1080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXroX:
1081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBroX:
1082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBroX:
1083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDroX:
1084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHroX:
1085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHroX:
1086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQroX:
1087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSroX:
1088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWroX:
1089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXroX:
1090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1091dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val = MI->getOperand(3).getImm();
1092dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getMemExtendType(Val);
1093dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ExtType != AArch64_AM::UXTX) || AArch64_AM::getMemDoShift(Val);
1094dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
1096dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
109772062f5744557e270a38192554c3126ea5f97434Tim Northover
1098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Check all MachineMemOperands for a hint to suppress pairing.
1099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr *MI) const {
1100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits) &&
1101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Too many target MO flags");
1102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (auto *MM : MI->memoperands()) {
1103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MM->getFlags() &
1104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        (MOSuppressPair << MachineMemOperand::MOTargetStartBit)) {
1105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
1106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
110772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
1109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
111072062f5744557e270a38192554c3126ea5f97434Tim Northover
1111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Set a flag on the first MachineMemOperand to suppress pairing.
1112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::suppressLdStPair(MachineInstr *MI) const {
1113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->memoperands_empty())
1114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
111572062f5744557e270a38192554c3126ea5f97434Tim Northover
1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits) &&
1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Too many target MO flags");
1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  (*MI->memoperands_begin())
1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ->setFlags(MOSuppressPair << MachineMemOperand::MOTargetStartBit);
1120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool
1123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64InstrInfo::getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       unsigned &Offset,
1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       const TargetRegisterInfo *TRI) const {
1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (LdSt->getOpcode()) {
1127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
1138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
1139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!LdSt->getOperand(1).isReg() || !LdSt->getOperand(2).isImm())
1140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BaseReg = LdSt->getOperand(1).getReg();
1142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineFunction &MF = *LdSt->getParent()->getParent();
1143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Width = getRegClass(LdSt->getDesc(), 0, TRI, MF)->getSize();
1144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = LdSt->getOperand(2).getImm() * Width;
1145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
1146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
114872062f5744557e270a38192554c3126ea5f97434Tim Northover
1149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Detect opportunities for ldp/stp formation.
1150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines///
1151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Only called for LdSt for which getLdStBaseRegImmOfs returns true.
1152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::shouldClusterLoads(MachineInstr *FirstLdSt,
1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          MachineInstr *SecondLdSt,
1154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          unsigned NumLoads) const {
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Only cluster up to a single pair.
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NumLoads > 1)
1157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (FirstLdSt->getOpcode() != SecondLdSt->getOpcode())
1159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // getLdStBaseRegImmOfs guarantees that oper 2 isImm.
1161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Ofs1 = FirstLdSt->getOperand(2).getImm();
1162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Allow 6 bits of positive range.
1163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Ofs1 > 64)
1164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The caller should already have ordered First/SecondLdSt by offset.
1166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Ofs2 = SecondLdSt->getOperand(2).getImm();
1167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Ofs1 + 1 == Ofs2;
1168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::shouldScheduleAdjacent(MachineInstr *First,
1171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              MachineInstr *Second) const {
1172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Cyclone can fuse CMN, CMP followed by Bcc.
1173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: B0 can also fuse:
1175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // AND, BIC, ORN, ORR, or EOR (optional S) followed by Bcc or CBZ or CBNZ.
1176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Second->getOpcode() != AArch64::Bcc)
1177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (First->getOpcode()) {
1179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
1182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWri:
1184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXri:
1187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
118872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
118972062f5744557e270a38192554c3126ea5f97434Tim Northover}
119072062f5744557e270a38192554c3126ea5f97434Tim Northover
1191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
1192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         int FrameIx,
1193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         uint64_t Offset,
1194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         const MDNode *MDPtr,
1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         DebugLoc DL) const {
1196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE))
1197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addFrameIndex(FrameIx)
1198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addImm(0)
1199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addImm(Offset)
1200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addMetadata(MDPtr);
1201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return &*MIB;
120272062f5744557e270a38192554c3126ea5f97434Tim Northover}
120372062f5744557e270a38192554c3126ea5f97434Tim Northover
1204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const MachineInstrBuilder &AddSubReg(const MachineInstrBuilder &MIB,
1205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned Reg, unsigned SubIdx,
1206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned State,
1207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            const TargetRegisterInfo *TRI) {
1208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!SubIdx)
1209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MIB.addReg(Reg, State);
121072062f5744557e270a38192554c3126ea5f97434Tim Northover
1211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TargetRegisterInfo::isPhysicalRegister(Reg))
1212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
1213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MIB.addReg(Reg, State, SubIdx);
1214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
121572062f5744557e270a38192554c3126ea5f97434Tim Northover
1216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg,
1217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        unsigned NumRegs) {
1218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We really want the positive remainder mod 32 here, that happens to be
1219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // easily obtainable with a mask.
1220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return ((DestReg - SrcReg) & 0x1f) < NumRegs;
1221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
122272062f5744557e270a38192554c3126ea5f97434Tim Northover
1223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::copyPhysRegTuple(
1224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL,
1225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode,
1226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm::ArrayRef<unsigned> Indices) const {
1227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(getSubTarget().hasNEON() &&
1228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Unexpected register copy without NEON");
1229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = &getRegisterInfo();
1230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
1231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
1232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumRegs = Indices.size();
1233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int SubReg = 0, End = NumRegs, Incr = 1;
1235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (forwardCopyWillClobberTuple(DestEncoding, SrcEncoding, NumRegs)) {
1236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SubReg = NumRegs - 1;
1237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    End = -1;
1238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Incr = -1;
1239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
124072062f5744557e270a38192554c3126ea5f97434Tim Northover
1241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (; SubReg != End; SubReg += Incr) {
1242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstrBuilder &MIB = BuildMI(MBB, I, DL, get(Opcode));
1243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI);
1244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI);
1245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI);
1246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
1250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock::iterator I, DebugLoc DL,
1251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   unsigned DestReg, unsigned SrcReg,
1252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   bool KillSrc) const {
1253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR32spRegClass.contains(DestReg) &&
1254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (AArch64::GPR32spRegClass.contains(SrcReg) || SrcReg == AArch64::WZR)) {
1255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI = &getRegisterInfo();
1256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If either operand is WSP, expand to ADD #0.
1259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Subtarget.hasZeroCycleRegMove()) {
1260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Cyclone recognizes "ADD Xd, Xn, #0" as a zero-cycle register move.
1261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32,
1262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                     &AArch64::GPR64spRegClass);
1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32,
1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                    &AArch64::GPR64spRegClass);
1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // This instruction is reading and writing X registers.  This may upset
1266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // the register scavenger and machine verifier, so we need to indicate
1267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // that we are reading an undefined value from SrcRegX, but a proper
1268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // value from SrcReg.
1269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestRegX)
1270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcRegX, RegState::Undef)
1271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(0)
1272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0))
1273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
1274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
1275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ADDWri), DestReg)
1276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, getKillRegState(KillSrc))
1277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(0)
1278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
127972062f5744557e270a38192554c3126ea5f97434Tim Northover      }
1280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroing()) {
1281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg).addImm(0).addImm(
1282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Subtarget.hasZeroCycleRegMove()) {
1285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Cyclone recognizes "ORR Xd, XZR, Xm" as a zero-cycle register move.
1286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32,
1287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                     &AArch64::GPR64spRegClass);
1288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32,
1289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                    &AArch64::GPR64spRegClass);
1290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // This instruction is reading and writing X registers.  This may upset
1291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // the register scavenger and machine verifier, so we need to indicate
1292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // that we are reading an undefined value from SrcRegX, but a proper
1293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // value from SrcReg.
1294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestRegX)
1295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(AArch64::XZR)
1296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcRegX, RegState::Undef)
1297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
1298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
1299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Otherwise, expand to ORR WZR.
1300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ORRWrr), DestReg)
1301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(AArch64::WZR)
1302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, getKillRegState(KillSrc));
1303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
1304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
130772062f5744557e270a38192554c3126ea5f97434Tim Northover
1308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64spRegClass.contains(DestReg) &&
1309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) {
1310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DestReg == AArch64::SP || SrcReg == AArch64::SP) {
1311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If either operand is SP, expand to ADD #0.
1312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestReg)
1313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc))
1314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
1315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroing()) {
1317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestReg).addImm(0).addImm(
1318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Otherwise, expand to ORR XZR.
1321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestReg)
1322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(AArch64::XZR)
1323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
132472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
132772062f5744557e270a38192554c3126ea5f97434Tim Northover
1328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DDDD register quad by copying the individual sub-registers.
1329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDDDRegClass.contains(DestReg) &&
1330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDDDRegClass.contains(SrcReg)) {
1331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::dsub2, AArch64::dsub3 };
1333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
133772062f5744557e270a38192554c3126ea5f97434Tim Northover
1338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DDD register triple by copying the individual sub-registers.
1339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDDRegClass.contains(DestReg) &&
1340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDDRegClass.contains(SrcReg)) {
1341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::dsub2 };
1343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
134772062f5744557e270a38192554c3126ea5f97434Tim Northover
1348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DD register pair by copying the individual sub-registers.
1349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDRegClass.contains(DestReg) &&
1350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDRegClass.contains(SrcReg)) {
1351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1 };
1352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQQQ register quad by copying the individual sub-registers.
1358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQQQRegClass.contains(DestReg) &&
1359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQQQRegClass.contains(SrcReg)) {
1360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::qsub2, AArch64::qsub3 };
1362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQQ register triple by copying the individual sub-registers.
1368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQQRegClass.contains(DestReg) &&
1369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQQRegClass.contains(SrcReg)) {
1370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::qsub2 };
1372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQ register pair by copying the individual sub-registers.
1378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQRegClass.contains(DestReg) &&
1379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQRegClass.contains(SrcReg)) {
1380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1 };
1381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
138572062f5744557e270a38192554c3126ea5f97434Tim Northover
1386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR128RegClass.contains(DestReg) &&
1387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR128RegClass.contains(SrcReg)) {
1388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if(getSubTarget().hasNEON()) {
1389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::STRQpre))
1394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP, RegState::Define)
1395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc))
1396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP)
1397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(-16);
1398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::LDRQpre))
1399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP, RegState::Define)
1400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(DestReg, RegState::Define)
1401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP)
1402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(16);
140372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
140672062f5744557e270a38192554c3126ea5f97434Tim Northover
1407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.contains(DestReg) &&
1408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR64RegClass.contains(SrcReg)) {
1409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if(getSubTarget().hasNEON()) {
1410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub,
1411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub,
1413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVDr), DestReg)
1419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
142372062f5744557e270a38192554c3126ea5f97434Tim Northover
1424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR32RegClass.contains(DestReg) &&
1425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.contains(SrcReg)) {
1426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if(getSubTarget().hasNEON()) {
1427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub,
1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub,
1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
144072062f5744557e270a38192554c3126ea5f97434Tim Northover
1441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR16RegClass.contains(DestReg) &&
1442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR16RegClass.contains(SrcReg)) {
1443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if(getSubTarget().hasNEON()) {
1444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR32RegClass);
1454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR32RegClass);
1456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
146172062f5744557e270a38192554c3126ea5f97434Tim Northover
1462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR8RegClass.contains(DestReg) &&
1463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR8RegClass.contains(SrcReg)) {
1464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if(getSubTarget().hasNEON()) {
1465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR32RegClass);
1475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR32RegClass);
1477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
147972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copies between GPR64 and FPR64.
1484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.contains(DestReg) &&
1485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR64RegClass.contains(SrcReg)) {
1486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVXDr), DestReg)
1487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64RegClass.contains(DestReg) &&
1491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR64RegClass.contains(SrcReg)) {
1492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVDXr), DestReg)
1493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copies between GPR32 and FPR32.
1497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR32RegClass.contains(DestReg) &&
1498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR32RegClass.contains(SrcReg)) {
1499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVWSr), DestReg)
1500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR32RegClass.contains(DestReg) &&
1504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.contains(SrcReg)) {
1505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVSWr), DestReg)
1506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
150972062f5744557e270a38192554c3126ea5f97434Tim Northover
1510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (DestReg == AArch64::NZCV) {
1511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy");
1512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::MSR))
1513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64SysReg::NZCV)
1514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcReg, getKillRegState(KillSrc))
1515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define);
1516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SrcReg == AArch64::NZCV) {
1520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy");
1521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::MRS))
1522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(DestReg)
1523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64SysReg::NZCV)
1524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc));
1525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("unimplemented reg-to-reg copy");
1529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::storeRegToStackSlot(
1532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg,
1533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isKill, int FI, const TargetRegisterClass *RC,
1534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI) const {
1535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DebugLoc DL;
1536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MBBI != MBB.end())
1537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DL = MBBI->getDebugLoc();
1538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction &MF = *MBB.getParent();
1539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFrameInfo &MFI = *MF.getFrameInfo();
1540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Align = MFI.getObjectAlignment(FI);
1541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachinePointerInfo PtrInfo(PseudoSourceValue::getFixedStack(FI));
1543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineMemOperand *MMO = MF.getMachineMemOperand(
1544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PtrInfo, MachineMemOperand::MOStore, MFI.getObjectSize(FI), Align);
1545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
1546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Offset = true;
1547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RC->getSize()) {
1548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1:
1549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRBui;
1551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2:
1553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRHui;
1555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4:
1557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRWui;
1559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(SrcReg))
1560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR32RegClass);
1561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(SrcReg != AArch64::WSP);
1563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRSui;
1565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 8:
1567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRXui;
1569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(SrcReg))
1570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass);
1571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(SrcReg != AArch64::SP);
1573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRDui;
1575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 16:
1577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRQui;
1579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Twov1d, Offset = false;
1583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 24:
1586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Threev1d, Offset = false;
1590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 32:
1593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Fourv1d, Offset = false;
1597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Twov2d, Offset = false;
160172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 48:
1604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Threev2d, Offset = false;
1608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 64:
1611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Fourv2d, Offset = false;
1615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && "Unknown register class");
1619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstrBuilder &MI = BuildMI(MBB, MBBI, DL, get(Opc))
1621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addReg(SrcReg, getKillRegState(isKill))
1622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addFrameIndex(FI);
1623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset)
1625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.addImm(0);
1626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI.addMemOperand(MMO);
1627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::loadRegFromStackSlot(
1630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg,
1631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int FI, const TargetRegisterClass *RC,
1632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI) const {
1633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DebugLoc DL;
1634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MBBI != MBB.end())
1635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DL = MBBI->getDebugLoc();
1636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction &MF = *MBB.getParent();
1637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFrameInfo &MFI = *MF.getFrameInfo();
1638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Align = MFI.getObjectAlignment(FI);
1639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachinePointerInfo PtrInfo(PseudoSourceValue::getFixedStack(FI));
1640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineMemOperand *MMO = MF.getMachineMemOperand(
1641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PtrInfo, MachineMemOperand::MOLoad, MFI.getObjectSize(FI), Align);
164272062f5744557e270a38192554c3126ea5f97434Tim Northover
1643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
1644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Offset = true;
1645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RC->getSize()) {
1646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1:
1647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRBui;
1649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2:
1651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRHui;
1653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4:
1655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRWui;
1657dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(DestReg))
1658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR32RegClass);
1659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(DestReg != AArch64::WSP);
1661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRSui;
1663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 8:
1665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRXui;
1667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(DestReg))
1668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR64RegClass);
1669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(DestReg != AArch64::SP);
1671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRDui;
1673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 16:
1675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRQui;
1677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Twov1d, Offset = false;
168172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 24:
1684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Threev1d, Offset = false;
1688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 32:
1691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Fourv1d, Offset = false;
1695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1698dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Twov2d, Offset = false;
1699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 48:
1702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Threev2d, Offset = false;
1706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 64:
1709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(getSubTarget().hasNEON() &&
1711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Fourv2d, Offset = false;
1713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && "Unknown register class");
1717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstrBuilder &MI = BuildMI(MBB, MBBI, DL, get(Opc))
1719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addReg(DestReg, getDefRegState(true))
1720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addFrameIndex(FI);
1721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset)
1722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.addImm(0);
1723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI.addMemOperand(MMO);
1724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid llvm::emitFrameOffset(MachineBasicBlock &MBB,
1727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           MachineBasicBlock::iterator MBBI, DebugLoc DL,
1728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           unsigned DestReg, unsigned SrcReg, int Offset,
1729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           const AArch64InstrInfo *TII,
1730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           MachineInstr::MIFlag Flag, bool SetNZCV) {
1731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (DestReg == SrcReg && Offset == 0)
1732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSub = Offset < 0;
1735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isSub)
1736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = -Offset;
1737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: If the offset won't fit in 24-bits, compute the offset into a
1739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // scratch register.  If DestReg is a virtual register, use it as the
1740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // scratch register; otherwise, create a new virtual register (to be
1741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // replaced by the scavenger at the end of PEI).  That case can be optimized
1742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // slightly if DestReg is SP which is always 16-byte aligned, so the scratch
1743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // register can be loaded with offset%8 and the add/sub can use an extending
1744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // instruction with LSL#3.
1745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Currently the function handles any offsets but generates a poor sequence
1746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // of code.
1747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //  assert(Offset < (1 << 24) && "unimplemented reg plus immediate");
1748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc;
1750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SetNZCV)
1751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri;
1752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else
1753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri;
1754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned MaxEncoding = 0xfff;
1755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned ShiftSize = 12;
1756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned MaxEncodableValue = MaxEncoding << ShiftSize;
1757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (((unsigned)Offset) >= (1 << ShiftSize)) {
1758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ThisVal;
1759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (((unsigned)Offset) > MaxEncodableValue) {
1760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ThisVal = MaxEncodableValue;
1761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ThisVal = Offset & MaxEncodableValue;
1763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert((ThisVal >> ShiftSize) <= MaxEncoding &&
1765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Encoding cannot handle value that big");
1766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
1767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg)
1768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(ThisVal >> ShiftSize)
1769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftSize))
1770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .setMIFlag(Flag);
1771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = DestReg;
1773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset -= ThisVal;
1774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Offset == 0)
1775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
1778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcReg)
1779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(Offset)
1780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0))
1781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .setMIFlag(Flag);
178272062f5744557e270a38192554c3126ea5f97434Tim Northover}
178372062f5744557e270a38192554c3126ea5f97434Tim Northover
1784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMachineInstr *
1785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
1786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        const SmallVectorImpl<unsigned> &Ops,
1787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        int FrameIndex) const {
1788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This is a bit of a hack. Consider this instruction:
1789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //   %vreg0<def> = COPY %SP; GPR64all:%vreg0
1791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We explicitly chose GPR64all for the virtual register so such a copy might
1793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // be eliminated by RegisterCoalescer. However, that may not be possible, and
1794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // %vreg0 may even spill. We can't spill %SP, and since it is in the GPR64all
1795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // register class, TargetInstrInfo::foldMemoryOperand() is going to try.
1796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // To prevent that, we are going to constrain the %vreg0 register class here.
1798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // <rdar://problem/11522048>
1800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->isCopy()) {
1802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
1803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SrcReg = MI->getOperand(1).getReg();
1804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SrcReg == AArch64::SP &&
1805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TargetRegisterInfo::isVirtualRegister(DstReg)) {
1806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MF.getRegInfo().constrainRegClass(DstReg, &AArch64::GPR64RegClass);
1807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
1808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DstReg == AArch64::SP &&
1810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TargetRegisterInfo::isVirtualRegister(SrcReg)) {
1811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass);
1812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
1813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Cannot fold.
1817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
1818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesint llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
1821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    bool *OutUseUnscaledOp,
1822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned *OutUnscaledOp,
1823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    int *EmittableOffset) {
1824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Scale = 1;
1825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsSigned = false;
1826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The ImmIdx should be changed case by case if it is not 2.
1827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ImmIdx = 2;
1828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned UnscaledOp = 0;
1829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Set output values in case of early exit.
1830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (EmittableOffset)
1831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *EmittableOffset = 0;
1832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUseUnscaledOp)
1833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUseUnscaledOp = false;
1834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUnscaledOp)
1835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUnscaledOp = 0;
1836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI.getOpcode()) {
1837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(0 && "unhandled opcode in rewriteAArch64FrameIndex");
1839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Vector spills/fills can't take an immediate offset.
1840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Twov2d:
1841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Threev2d:
1842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Fourv2d:
1843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Twov1d:
1844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Threev1d:
1845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Fourv1d:
1846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Twov2d:
1847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Threev2d:
1848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Fourv2d:
1849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Twov1d:
1850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Threev1d:
1851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Fourv1d:
1852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64FrameOffsetCannotUpdate;
1853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::PRFMui:
1854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::PRFUMi;
1856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
1858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURXi;
1860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
1862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURWi;
1864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBui:
1866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURBi;
1868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHui:
1870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURHi;
1872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSi;
1876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURDi;
1880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
1883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURQi;
1884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBui:
1886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURBBi;
1888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHui:
1890dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURHHi;
1892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXui:
1894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSBXi;
1896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWui:
1898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSBWi;
1900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXui:
1902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSHXi;
1904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWui:
1906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSHWi;
1908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWui:
1910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSWi;
1912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURXi;
1917dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURWi;
1921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBui:
1923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURBi;
1925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHui:
1927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURHi;
1929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURSi;
1933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURDi;
1937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
1940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURQi;
1941dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBui:
1943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURBBi;
1945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHui:
1947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURHHi;
1949dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPXi:
1952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPDi:
1953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPXi:
1954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPDi:
1955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
1956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPQi:
1959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPQi:
1960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
1961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
1962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPWi:
1964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSi:
1965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPWi:
1966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPSi:
1967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
1968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURXi:
1972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURWi:
1973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURBi:
1974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURHi:
1975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSi:
1976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURDi:
1977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURQi:
1978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURHHi:
1979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURBBi:
1980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSBXi:
1981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSBWi:
1982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSHXi:
1983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSHWi:
1984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSWi:
1985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURXi:
1986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURWi:
1987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURBi:
1988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURHi:
1989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURSi:
1990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURDi:
1991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURQi:
1992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURBBi:
1993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURHHi:
1994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Offset += MI.getOperand(ImmIdx).getImm() * Scale;
1999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool useUnscaledOp = false;
2001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the offset doesn't match the scale, we rewrite the instruction to
2002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // use the unscaled instruction instead. Likewise, if we have a negative
2003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // offset (and have an unscaled op to use).
2004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0))
2005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    useUnscaledOp = true;
2006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Use an unscaled addressing mode if the instruction has a negative offset
2008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // (or if the instruction is already using an unscaled addressing mode).
2009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned MaskBits;
2010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsSigned) {
2011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // ldp/stp instructions.
2012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 7;
2013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset /= Scale;
2014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (UnscaledOp == 0 || useUnscaledOp) {
2015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 9;
2016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
2017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
2018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
2019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 12;
2020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = false;
2021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset /= Scale;
2022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Attempt to fold address computation.
2025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int MaxOff = (1 << (MaskBits - IsSigned)) - 1;
2026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int MinOff = (IsSigned ? (-MaxOff - 1) : 0);
2027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset >= MinOff && Offset <= MaxOff) {
2028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (EmittableOffset)
2029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      *EmittableOffset = Offset;
2030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = 0;
2031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
2032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int NewOff = Offset < 0 ? MinOff : MaxOff;
2033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (EmittableOffset)
2034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      *EmittableOffset = NewOff;
2035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = (Offset - NewOff) * Scale;
2036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUseUnscaledOp)
2038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUseUnscaledOp = useUnscaledOp;
2039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUnscaledOp)
2040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUnscaledOp = UnscaledOp;
2041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return AArch64FrameOffsetCanUpdate |
2042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         (Offset == 0 ? AArch64FrameOffsetIsLegal : 0);
2043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
2046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned FrameReg, int &Offset,
2047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    const AArch64InstrInfo *TII) {
2048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opcode = MI.getOpcode();
2049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ImmIdx = FrameRegIdx + 1;
2050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) {
2052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset += MI.getOperand(ImmIdx).getImm();
2053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(),
2054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    MI.getOperand(0).getReg(), FrameReg, Offset, TII,
2055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri));
2056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.eraseFromParent();
2057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = 0;
2058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int NewOffset;
2062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned UnscaledOp;
2063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool UseUnscaledOp;
2064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Status = isAArch64FrameOffsetLegal(MI, Offset, &UseUnscaledOp,
2065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         &UnscaledOp, &NewOffset);
2066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Status & AArch64FrameOffsetCanUpdate) {
2067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Status & AArch64FrameOffsetIsLegal)
2068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Replace the FrameIndex with FrameReg.
2069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
2070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (UseUnscaledOp)
2071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MI.setDesc(TII->get(UnscaledOp));
2072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.getOperand(ImmIdx).ChangeToImmediate(NewOffset);
2074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Offset == 0;
2075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
2081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  NopInst.setOpcode(AArch64::HINT);
2082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  NopInst.addOperand(MCOperand::CreateImm(0));
2083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2084