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 {
38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MachineBasicBlock &MBB = *MI->getParent();
39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MachineFunction *MF = MBB.getParent();
40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (MI->getOpcode() == AArch64::INLINEASM)
43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI);
4472062f5744557e270a38192554c3126ea5f97434Tim Northover
45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCInstrDesc &Desc = MI->getDesc();
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Desc.getOpcode()) {
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Anything not explicitly designated otherwise is a nomal 4-byte insn.
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 4;
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::DBG_VALUE:
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::EH_LABEL:
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::IMPLICIT_DEF:
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::KILL:
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
5572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
5672062f5744557e270a38192554c3126ea5f97434Tim Northover
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("GetInstSizeInBytes()- Unable to determin insn size");
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            SmallVectorImpl<MachineOperand> &Cond) {
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Block ends with fall-through condbranch.
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (LastInst->getOpcode()) {
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unknown branch instruction?");
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::Bcc:
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(1).getMBB();
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBZW:
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBZX:
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBNZW:
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CBNZX:
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(1).getMBB();
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(-1));
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBZW:
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBZX:
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBNZW:
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::TBNZX:
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Target = LastInst->getOperand(2).getMBB();
84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(-1));
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(0));
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond.push_back(LastInst->getOperand(1));
8872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
8972062f5744557e270a38192554c3126ea5f97434Tim Northover}
9072062f5744557e270a38192554c3126ea5f97434Tim Northover
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Branch analysis.
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock *&TBB,
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock *&FBB,
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   SmallVectorImpl<MachineOperand> &Cond,
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   bool AllowModify) const {
9772062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block has no terminators, it just falls into the block after it.
9872062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
9972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin())
10072062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
10172062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
10272062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
10372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
10472062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
10572062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
10672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
10772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!isUnpredicatedTerminator(I))
10872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
10972062f5744557e270a38192554c3126ea5f97434Tim Northover
11072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the last instruction in the block.
11172062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *LastInst = I;
11272062f5744557e270a38192554c3126ea5f97434Tim Northover
11372062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there is only one terminator instruction, process it.
11472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned LastOpc = LastInst->getOpcode();
11572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isUncondBranchOpcode(LastOpc)) {
11772062f5744557e270a38192554c3126ea5f97434Tim Northover      TBB = LastInst->getOperand(0).getMBB();
11872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
11972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isCondBranchOpcode(LastOpc)) {
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Block ends with fall-through condbranch.
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      parseCondBranch(LastInst, TBB, Cond);
12372062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
12472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true; // Can't handle indirect branch.
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12772062f5744557e270a38192554c3126ea5f97434Tim Northover
12872062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the instruction before it if it is a terminator.
12972062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *SecondLastInst = I;
13072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SecondLastOpc = SecondLastInst->getOpcode();
13172062f5744557e270a38192554c3126ea5f97434Tim Northover
13272062f5744557e270a38192554c3126ea5f97434Tim Northover  // If AllowModify is true and the block ends with two or more unconditional
13372062f5744557e270a38192554c3126ea5f97434Tim Northover  // branches, delete all but the first unconditional branch.
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AllowModify && isUncondBranchOpcode(LastOpc)) {
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    while (isUncondBranchOpcode(SecondLastOpc)) {
13672062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst->eraseFromParent();
13772062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst = SecondLastInst;
13872062f5744557e270a38192554c3126ea5f97434Tim Northover      LastOpc = LastInst->getOpcode();
13972062f5744557e270a38192554c3126ea5f97434Tim Northover      if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
14072062f5744557e270a38192554c3126ea5f97434Tim Northover        // Return now the only terminator is an unconditional branch.
14172062f5744557e270a38192554c3126ea5f97434Tim Northover        TBB = LastInst->getOperand(0).getMBB();
14272062f5744557e270a38192554c3126ea5f97434Tim Northover        return false;
14372062f5744557e270a38192554c3126ea5f97434Tim Northover      } else {
14472062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastInst = I;
14572062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastOpc = SecondLastInst->getOpcode();
14672062f5744557e270a38192554c3126ea5f97434Tim Northover      }
14772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
14872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14972062f5744557e270a38192554c3126ea5f97434Tim Northover
15072062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there are three terminators, we don't know what sort of block this is.
15172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
15272062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
15372062f5744557e270a38192554c3126ea5f97434Tim Northover
15472062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with a B and a Bcc, handle it.
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    parseCondBranch(SecondLastInst, TBB, Cond);
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    FBB = LastInst->getOperand(0).getMBB();
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
16072062f5744557e270a38192554c3126ea5f97434Tim Northover
16172062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with two unconditional branches, handle it.  The second
16272062f5744557e270a38192554c3126ea5f97434Tim Northover  // one is not executed, so remove it.
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
16472062f5744557e270a38192554c3126ea5f97434Tim Northover    TBB = SecondLastInst->getOperand(0).getMBB();
16572062f5744557e270a38192554c3126ea5f97434Tim Northover    I = LastInst;
16672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (AllowModify)
16772062f5744557e270a38192554c3126ea5f97434Tim Northover      I->eraseFromParent();
16872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
16972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
17072062f5744557e270a38192554c3126ea5f97434Tim Northover
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // ...likewise if it ends with an indirect branch followed by an unconditional
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // branch.
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    I = LastInst;
175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AllowModify)
176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      I->eraseFromParent();
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
18072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise, can't handle this.
18172062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
18272062f5744557e270a38192554c3126ea5f97434Tim Northover}
18372062f5744557e270a38192554c3126ea5f97434Tim Northover
18472062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64InstrInfo::ReverseBranchCondition(
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVectorImpl<MachineOperand> &Cond) const {
186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cond[0].getImm() != -1) {
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Regular Bcc
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64CC::CondCode CC = (AArch64CC::CondCode)(int)Cond[0].getImm();
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Cond[0].setImm(AArch64CC::getInvertedCondCode(CC));
190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Folded compare-and-branch
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown conditional branch!");
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZW:
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBNZW);
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZW:
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBZW);
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZX:
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBNZX);
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZX:
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::CBZX);
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZW:
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBNZW);
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZW:
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBZW);
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZX:
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBNZX);
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZX:
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Cond[1].setImm(AArch64::TBZX);
218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
22072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
22172062f5744557e270a38192554c3126ea5f97434Tim Northover
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
22372062f5744557e270a38192554c3126ea5f97434Tim Northover}
22472062f5744557e270a38192554c3126ea5f97434Tim Northover
22572062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
22672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == MBB.begin())
228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
22972062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
23072062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
23172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
23272062f5744557e270a38192554c3126ea5f97434Tim Northover      return 0;
23372062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
23472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!isUncondBranchOpcode(I->getOpcode()) &&
236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      !isCondBranchOpcode(I->getOpcode()))
23772062f5744557e270a38192554c3126ea5f97434Tim Northover    return 0;
23872062f5744557e270a38192554c3126ea5f97434Tim Northover
23972062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
24072062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
24172062f5744557e270a38192554c3126ea5f97434Tim Northover
24272062f5744557e270a38192554c3126ea5f97434Tim Northover  I = MBB.end();
24372062f5744557e270a38192554c3126ea5f97434Tim Northover
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == MBB.begin())
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 1;
24672062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!isCondBranchOpcode(I->getOpcode()))
24872062f5744557e270a38192554c3126ea5f97434Tim Northover    return 1;
24972062f5744557e270a38192554c3126ea5f97434Tim Northover
25072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
25172062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
25272062f5744557e270a38192554c3126ea5f97434Tim Northover  return 2;
25372062f5744557e270a38192554c3126ea5f97434Tim Northover}
25472062f5744557e270a38192554c3126ea5f97434Tim Northover
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::instantiateCondBranch(
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, DebugLoc DL, MachineBasicBlock *TBB,
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const SmallVectorImpl<MachineOperand> &Cond) const {
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cond[0].getImm() != -1) {
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Regular Bcc
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(&MBB, DL, get(AArch64::Bcc)).addImm(Cond[0].getImm()).addMBB(TBB);
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Folded compare-and-branch
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstrBuilder MIB =
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(&MBB, DL, get(Cond[1].getImm())).addReg(Cond[2].getReg());
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond.size() > 3)
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MIB.addImm(Cond[3].getImm());
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MIB.addMBB(TBB);
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
27072062f5744557e270a38192554c3126ea5f97434Tim Northover
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::InsertBranch(
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const {
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Shouldn't be a fall through.
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!FBB) {
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond.empty()) // Unconditional branch?
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB);
280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      instantiateCondBranch(MBB, DL, TBB, Cond);
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 1;
283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Two-way conditional branch.
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  instantiateCondBranch(MBB, DL, TBB, Cond);
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB);
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 2;
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Find the original register that VReg is copied from.
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg) {
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (TargetRegisterInfo::isVirtualRegister(VReg)) {
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr *DefMI = MRI.getVRegDef(VReg);
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!DefMI->isFullCopy())
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return VReg;
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VReg = DefMI->getOperand(1).getReg();
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return VReg;
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Determine if VReg is defined by an instruction that can be folded into a
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// csel instruction. If so, return the folded opcode, and the replacement
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// register.
305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg,
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                unsigned *NewVReg = nullptr) {
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  VReg = removeCopies(MRI, VReg);
308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!TargetRegisterInfo::isVirtualRegister(VReg))
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.getRegClass(VReg));
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstr *DefMI = MRI.getVRegDef(VReg);
313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned SrcOpNum = 0;
315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (DefMI->getOpcode()) {
316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // if NZCV is used, do not fold.
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1)
320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // fall-through to ADDXri and ADDWri.
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri:
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWri:
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // add x, 1 -> csinc.
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!DefMI->getOperand(2).isImm() || DefMI->getOperand(2).getImm() != 1 ||
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        DefMI->getOperand(3).getImm() != 0)
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 1;
329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr;
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNXrr:
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNWrr: {
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // not x -> csinv, represented as orn dst, xzr, src.
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg());
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 2;
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr;
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // if NZCV is used, do not fold.
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1)
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // fall-through to SUBXrr and SUBWrr.
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrr:
350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrr: {
351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // neg x -> csneg, represented as sub dst, xzr, src.
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg());
353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ZReg != AArch64::XZR && ZReg != AArch64::WZR)
354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return 0;
355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcOpNum = 2;
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr;
357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
35972062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && SrcOpNum && "Missing parameters");
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NewVReg)
365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *NewVReg = DefMI->getOperand(SrcOpNum).getReg();
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Opc;
367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::canInsertSelect(
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineBasicBlock &MBB, const SmallVectorImpl<MachineOperand> &Cond,
371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned TrueReg, unsigned FalseReg, int &CondCycles, int &TrueCycles,
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int &FalseCycles) const {
373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check register classes.
374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterClass *RC =
376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!RC)
37872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Expanding cbz/tbz requires an extra cycle of latency on the condition.
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ExtraCondLat = Cond.size() != 1;
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // GPRs are handled by csel.
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Fold in x+1, -x, and ~x when applicable.
385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64allRegClass.hasSubClassEq(RC) ||
386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Single-cycle csel, csinc, csinv, and csneg.
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CondCycles = 1 + ExtraCondLat;
389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TrueCycles = FalseCycles = 1;
390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (canFoldIntoCSel(MRI, TrueReg))
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TrueCycles = 0;
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (canFoldIntoCSel(MRI, FalseReg))
393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FalseCycles = 0;
394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
39572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39672062f5744557e270a38192554c3126ea5f97434Tim Northover
397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Scalar floating point is handled by fcsel.
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Form fabs, fmin, and fmax when applicable.
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.hasSubClassEq(RC) ||
400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.hasSubClassEq(RC)) {
401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CondCycles = 5 + ExtraCondLat;
402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TrueCycles = FalseCycles = 2;
403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Can't do vectors.
40772062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
40872062f5744557e270a38192554c3126ea5f97434Tim Northover}
40972062f5744557e270a38192554c3126ea5f97434Tim Northover
410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    MachineBasicBlock::iterator I, DebugLoc DL,
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned DstReg,
413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    const SmallVectorImpl<MachineOperand> &Cond,
414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned TrueReg, unsigned FalseReg) const {
415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Parse the condition code, see parseCondBranch() above.
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode CC;
419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Cond.size()) {
420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unknown condition opcode in Cond");
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1: // b.cc
423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CC = AArch64CC::CondCode(Cond[0].getImm());
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 3: { // cbz/cbnz
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We must insert a compare against 0.
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Is64Bit;
428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
42972062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown branch opcode in Cond");
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZW:
432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 0;
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBZX:
436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 1;
437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZW:
440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 0;
441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::CBNZX:
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Is64Bit = 1;
445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SrcReg = Cond[2].getReg();
449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Is64Bit) {
450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // cmp reg, #0 is actually subs xzr, reg, #0.
451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.constrainRegClass(SrcReg, &AArch64::GPR64spRegClass);
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::SUBSXri), AArch64::XZR)
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0);
456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.constrainRegClass(SrcReg, &AArch64::GPR32spRegClass);
458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::SUBSWri), AArch64::WZR)
459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0);
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4: { // tbz/tbnz
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We must insert a tst instruction.
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Cond[1].getImm()) {
46872062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Unknown branch opcode in Cond");
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZW:
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBZX:
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::EQ;
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZW:
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::TBNZX:
476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::NE;
477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // cmp reg, #foo is actually ands xzr, reg, #1<<foo.
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW)
481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ANDSWri), AArch64::WZR)
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(Cond[2].getReg())
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32));
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ANDSXri), AArch64::XZR)
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(Cond[2].getReg())
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64));
490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterClass *RC = nullptr;
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool TryFold = false;
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MRI.constrainRegClass(DstReg, &AArch64::GPR64RegClass)) {
498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR64RegClass;
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::CSELXr;
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TryFold = true;
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::GPR32RegClass)) {
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR32RegClass;
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::CSELWr;
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TryFold = true;
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR64RegClass)) {
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::FPR64RegClass;
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::FCSELDrrr;
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR32RegClass)) {
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::FPR32RegClass;
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::FCSELSrrr;
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(RC && "Unsupported regclass");
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Try folding simple instructions into the csel.
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TryFold) {
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned NewVReg = 0;
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned FoldedOpc = canFoldIntoCSel(MRI, TrueReg, &NewVReg);
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (FoldedOpc) {
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The folded opcodes csinc, csinc and csneg apply the operation to
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // FalseReg, so we need to invert the condition.
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC = AArch64CC::getInvertedCondCode(CC);
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TrueReg = FalseReg;
523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else
524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FoldedOpc = canFoldIntoCSel(MRI, FalseReg, &NewVReg);
525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Fold the operation. Leave any dead instructions for DCE to clean up.
527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (FoldedOpc) {
528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FalseReg = NewVReg;
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = FoldedOpc;
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The extends the live range of NewVReg.
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.clearKillFlags(NewVReg);
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
53372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
53472062f5744557e270a38192554c3126ea5f97434Tim Northover
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Pull all virtual register into the appropriate class.
536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(TrueReg, RC);
537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(FalseReg, RC);
53872062f5744557e270a38192554c3126ea5f97434Tim Northover
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Insert the csel.
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(MBB, I, DL, get(Opc), DstReg).addReg(TrueReg).addReg(FalseReg).addImm(
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CC);
54272062f5744557e270a38192554c3126ea5f97434Tim Northover}
54372062f5744557e270a38192554c3126ea5f97434Tim Northover
54422c310d78ce9630af15b0de94c18a409705b7496Tim Murray// FIXME: this implementation should be micro-architecture dependent, so a
54522c310d78ce9630af15b0de94c18a409705b7496Tim Murray// micro-architecture target hook should be introduced here in future.
54622c310d78ce9630af15b0de94c18a409705b7496Tim Murraybool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr *MI) const {
54722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  if (!Subtarget.isCortexA57() && !Subtarget.isCortexA53())
54822c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return MI->isAsCheapAsAMove();
54922c310d78ce9630af15b0de94c18a409705b7496Tim Murray
55022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  switch (MI->getOpcode()) {
55122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  default:
55222c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return false;
55322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
55422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // add/sub on register without shift
55522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ADDWri:
55622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ADDXri:
55722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::SUBWri:
55822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::SUBXri:
55922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return (MI->getOperand(3).getImm() == 0);
56022c310d78ce9630af15b0de94c18a409705b7496Tim Murray
56122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // logical ops on immediate
56222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ANDWri:
56322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ANDXri:
56422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EORWri:
56522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EORXri:
56622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORRWri:
56722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORRXri:
56822c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return true;
56922c310d78ce9630af15b0de94c18a409705b7496Tim Murray
57022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // logical ops on register without shift
57122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ANDWrr:
57222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ANDXrr:
57322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::BICWrr:
57422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::BICXrr:
57522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EONWrr:
57622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EONXrr:
57722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EORWrr:
57822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::EORXrr:
57922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORNWrr:
58022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORNXrr:
58122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORRWrr:
58222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::ORRXrr:
58322c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return true;
58422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
58522c310d78ce9630af15b0de94c18a409705b7496Tim Murray
58622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  llvm_unreachable("Unknown opcode to check as cheap as a move!");
58722c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
58822c310d78ce9630af15b0de94c18a409705b7496Tim Murray
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             unsigned &SrcReg, unsigned &DstReg,
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             unsigned &SubIdx) const {
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI.getOpcode()) {
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBFMXri: // aka sxtw
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::UBFMXri: // aka uxtw
597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check for the 32 -> 64 bit extension case, these instructions can do
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // much more.
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI.getOperand(2).getImm() != 0 || MI.getOperand(3).getImm() != 31)
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This is a signed or unsigned 32 -> 64 bit extension.
602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI.getOperand(1).getReg();
603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DstReg = MI.getOperand(0).getReg();
604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SubIdx = AArch64::sub_32;
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// analyzeCompare - For a comparison instruction, return the source registers
610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if the comparison instruction can be analyzed.
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      unsigned &SrcReg2, int &CmpMask,
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      int &CmpValue) const {
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrs:
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrx:
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrs:
623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx:
624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrr:
625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrs:
626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrx:
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrr:
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrs:
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx:
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Replace SUBSWrr with SUBWrr if NZCV is not used.
631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = MI->getOperand(2).getReg();
633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = 0;
635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = 0;
642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = MI->getOperand(2).getImm();
644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWri:
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXri:
647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // ANDS does not use the same encoding scheme as the others xxxS
648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // instructions.
649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = MI->getOperand(1).getReg();
650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg2 = 0;
651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpMask = ~0;
652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpValue = AArch64_AM::decodeLogicalImmediate(
653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).getImm(),
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOpcode() == AArch64::ANDSWri ? 32 : 64);
655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
657dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool UpdateOperandRegClass(MachineInstr *Instr) {
662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineBasicBlock *MBB = Instr->getParent();
663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MBB && "Can't get MachineBasicBlock here");
664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction *MF = MBB->getParent();
665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MF && "Can't get MachineFunction here");
666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetMachine *TM = &MF->getTarget();
667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetInstrInfo *TII = TM->getInstrInfo();
668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = TM->getRegisterInfo();
669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineRegisterInfo *MRI = &MF->getRegInfo();
670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned OpIdx = 0, EndIdx = Instr->getNumOperands(); OpIdx < EndIdx;
672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       ++OpIdx) {
673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineOperand &MO = Instr->getOperand(OpIdx);
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterClass *OpRegCstraints =
675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Instr->getRegClassConstraint(OpIdx, TII, TRI);
676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If there's no constraint, there's nothing to do.
678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!OpRegCstraints)
679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If the operand is a frame index, there's nothing to do here.
681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A frame index operand will resolve correctly during PEI.
682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MO.isFI())
683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MO.isReg() &&
686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Operand has register constraints without being a register!");
687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Reg = MO.getReg();
689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!OpRegCstraints->contains(Reg))
691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!OpRegCstraints->hasSubClassEq(MRI->getRegClass(Reg)) &&
693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               !MRI->constrainRegClass(Reg, OpRegCstraints))
694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
69572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
69672062f5744557e270a38192554c3126ea5f97434Tim Northover
697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
69872062f5744557e270a38192554c3126ea5f97434Tim Northover}
69972062f5744557e270a38192554c3126ea5f97434Tim Northover
700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// optimizeCompareInstr - Convert the instruction supplying the argument to the
701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// comparison into one that sets the zero bit in the flags register.
702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::optimizeCompareInstr(
703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int CmpValue, const MachineRegisterInfo *MRI) const {
705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Replace SUBSWrr with SUBWrr if NZCV is not used.
707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Cmp_NZCV = CmpInstr->findRegisterDefOperandIdx(AArch64::NZCV, true);
708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Cmp_NZCV != -1) {
709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned NewOpc;
710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (CmpInstr->getOpcode()) {
711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrr:      NewOpc = AArch64::ADDWrr; break;
714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWri:      NewOpc = AArch64::ADDWri; break;
715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrs:      NewOpc = AArch64::ADDWrs; break;
716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSWrx:      NewOpc = AArch64::ADDWrx; break;
717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrr:      NewOpc = AArch64::ADDXrr; break;
718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXri:      NewOpc = AArch64::ADDXri; break;
719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrs:      NewOpc = AArch64::ADDXrs; break;
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::ADDSXrx:      NewOpc = AArch64::ADDXrx; break;
721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrr:      NewOpc = AArch64::SUBWrr; break;
722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWri:      NewOpc = AArch64::SUBWri; break;
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrs:      NewOpc = AArch64::SUBWrs; break;
724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSWrx:      NewOpc = AArch64::SUBWrx; break;
725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrr:      NewOpc = AArch64::SUBXrr; break;
726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXri:      NewOpc = AArch64::SUBXri; break;
727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrs:      NewOpc = AArch64::SUBXrs; break;
728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::SUBSXrx:      NewOpc = AArch64::SUBXrx; break;
729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCInstrDesc &MCID = get(NewOpc);
732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpInstr->setDesc(MCID);
733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpInstr->RemoveOperand(Cmp_NZCV);
734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool succeeded = UpdateOperandRegClass(CmpInstr);
735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    (void)succeeded;
736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(succeeded && "Some operands reg class are incompatible!");
737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Continue only if we have a "ri" where immediate is zero.
741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CmpValue != 0 || SrcReg2 != 0)
742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // CmpInstr is a Compare instruction if destination register is not used.
745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MRI->use_nodbg_empty(CmpInstr->getOperand(0).getReg()))
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Get the unique definition of SrcReg.
749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MI)
751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We iterate backward, starting from the instruction before CmpInstr and
754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // stop when reaching the definition of the source register or done with the
755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // basic block, to check whether NZCV is used or modified in between.
756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineBasicBlock::iterator I = CmpInstr, E = MI,
757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              B = CmpInstr->getParent()->begin();
758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Early exit if CmpInstr is at the beginning of the BB.
760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (I == B)
761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check whether the definition of SrcReg is in the same basic block as
764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Compare. If not, we can't optimize away the Compare.
765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->getParent() != CmpInstr->getParent())
766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check that NZCV isn't set between the comparison instruction and the one we
769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // want to change.
770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = &getRegisterInfo();
771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (--I; I != E; --I) {
772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr &Instr = *I;
77372062f5744557e270a38192554c3126ea5f97434Tim Northover
774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Instr.modifiesRegister(AArch64::NZCV, TRI) ||
775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Instr.readsRegister(AArch64::NZCV, TRI))
776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // This instruction modifies or uses NZCV after the one we want to
777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // change. We can't do this transformation.
778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (I == B)
780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The 'and' is below the comparison instruction.
781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NewOpc = MI->getOpcode();
785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrr:
789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrr:
791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrr:
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrr:
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrr:    NewOpc = AArch64::ADDSWrr; break;
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWri:    NewOpc = AArch64::ADDSWri; break;
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrr:    NewOpc = AArch64::ADDSXrr; break;
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri:    NewOpc = AArch64::ADDSXri; break;
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADCWr:     NewOpc = AArch64::ADCSWr; break;
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADCXr:     NewOpc = AArch64::ADCSXr; break;
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrr:    NewOpc = AArch64::SUBSWrr; break;
804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWri:    NewOpc = AArch64::SUBSWri; break;
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrr:    NewOpc = AArch64::SUBSXrr; break;
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXri:    NewOpc = AArch64::SUBSXri; break;
807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBCWr:     NewOpc = AArch64::SBCSWr; break;
808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SBCXr:     NewOpc = AArch64::SBCSXr; break;
809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWri:    NewOpc = AArch64::ANDSWri; break;
810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXri:    NewOpc = AArch64::ANDSXri; break;
811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
81272062f5744557e270a38192554c3126ea5f97434Tim Northover
813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Scan forward for the use of NZCV.
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // When checking against MI: if it's a conditional code requires
815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // checking of V bit, then this is not safe to do.
816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // It is safe to remove CmpInstr if NZCV is redefined or killed.
817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If we are done with the basic block, we need to check whether NZCV is
818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // live-out.
819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsSafe = false;
820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MachineBasicBlock::iterator I = CmpInstr,
821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   E = CmpInstr->getParent()->end();
822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       !IsSafe && ++I != E;) {
823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstr &Instr = *I;
824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned IO = 0, EO = Instr.getNumOperands(); !IsSafe && IO != EO;
825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         ++IO) {
826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const MachineOperand &MO = Instr.getOperand(IO);
827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MO.isRegMask() && MO.clobbersPhysReg(AArch64::NZCV)) {
828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IsSafe = true;
829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!MO.isReg() || MO.getReg() != AArch64::NZCV)
832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        continue;
833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MO.isDef()) {
834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IsSafe = true;
835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
83772062f5744557e270a38192554c3126ea5f97434Tim Northover
838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Decode the condition code.
839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned Opc = Instr.getOpcode();
840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64CC::CondCode CC;
841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      switch (Opc) {
842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      default:
843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::Bcc:
845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CC = (AArch64CC::CondCode)Instr.getOperand(IO - 2).getImm();
846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINVWr:
848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINVXr:
849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINCWr:
850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSINCXr:
851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSELWr:
852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSELXr:
853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSNEGWr:
854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::CSNEGXr:
855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::FCSELSrrr:
856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64::FCSELDrrr:
857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CC = (AArch64CC::CondCode)Instr.getOperand(IO - 1).getImm();
858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // It is not safe to remove Compare instruction if Overflow(V) is used.
862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      switch (CC) {
863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      default:
864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // NZCV can be used multiple times, we should continue.
865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::VS:
867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::VC:
868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::GE:
869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::LT:
870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::GT:
871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case AArch64CC::LE:
872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
87372062f5744557e270a38192554c3126ea5f97434Tim Northover      }
87472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
87572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
87672062f5744557e270a38192554c3126ea5f97434Tim Northover
877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If NZCV is not killed nor re-defined, we should check whether it is
878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // live-out. If it is live-out, do not optimize.
879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!IsSafe) {
880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock *ParentBlock = CmpInstr->getParent();
881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (auto *MBB : ParentBlock->successors())
882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (MBB->isLiveIn(AArch64::NZCV))
883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Update the instruction to set NZCV.
887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI->setDesc(get(NewOpc));
888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  CmpInstr->eraseFromParent();
889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool succeeded = UpdateOperandRegClass(MI);
890dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  (void)succeeded;
891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(succeeded && "Some operands reg class are incompatible!");
892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI->addRegisterDefined(AArch64::NZCV, TRI);
893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
89472062f5744557e270a38192554c3126ea5f97434Tim Northover}
895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is this instruction has a non-zero immediate
897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::hasShiftedReg(const MachineInstr *MI) const {
898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrs:
902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrs:
903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrs:
904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrs:
905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWrs:
906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXrs:
907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWrs:
908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXrs:
909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICSWrs:
910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICSXrs:
911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICWrs:
912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::BICXrs:
913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Brr:
914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CBrr:
915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CHrr:
916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CWrr:
917dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32CXrr:
918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Hrr:
919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Wrr:
920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::CRC32Xrr:
921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EONWrs:
922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EONXrs:
923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EORWrs:
924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::EORXrs:
925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNWrs:
926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORNXrs:
927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRWrs:
928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRXrs:
929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrs:
930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrs:
931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrs:
932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrs:
933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(3).isImm()) {
934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned val = MI->getOperand(3).getImm();
935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return (val != 0);
936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
93872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
94072062f5744557e270a38192554c3126ea5f97434Tim Northover}
94172062f5744557e270a38192554c3126ea5f97434Tim Northover
942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is this instruction has a non-zero immediate
943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::hasExtendedReg(const MachineInstr *MI) const {
944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWrx:
948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx:
949dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXrx64:
950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWrx:
951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrx:
952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXrx64:
953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWrx:
954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx:
955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXrx64:
956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWrx:
957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrx:
958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXrx64:
959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(3).isImm()) {
960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned val = MI->getOperand(3).getImm();
961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return (val != 0);
962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
96585d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
96885d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply sets its single destination register
970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// to zero. This is equivalent to a register rename of the zero-register.
971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isGPRZero(const MachineInstr *MI) const {
972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::MOVZWi:
976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::MOVZXi: // movz Rd, #0 (LSL #0)
977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) {
978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 3 &&
979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(2).getImm() == 0 && "invalid MOVZi operands");
980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDWri: // and Rd, Rzr, #imm
984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::WZR;
985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDXri:
986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::XZR;
987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY:
988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MI->getOperand(1).getReg() == AArch64::WZR;
989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
99285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply renames a general register without
994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// modifying bits.
995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isGPRCopy(const MachineInstr *MI) const {
996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
99785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  default:
998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY: {
1000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // GPR32 copies will by lowered to ORRXrs
1001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
1002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (AArch64::GPR32RegClass.contains(DstReg) ||
1003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            AArch64::GPR64RegClass.contains(DstReg));
100485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
1005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRXrs: // orr Xd, Xzr, Xm (LSL #0)
1006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).getReg() == AArch64::XZR) {
1007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 4 &&
1008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(3).getImm() == 0 && "invalid ORRrs operands");
1009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
1010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri: // add Xd, Xn, #0 (LSL #0)
1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(2).getImm() == 0) {
1013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 4 &&
1014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             MI->getOperand(3).getImm() == 0 && "invalid ADDXri operands");
1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
101985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
102085d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Return true if this instruction simply renames a general register without
1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// modifying bits.
1023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isFPRCopy(const MachineInstr *MI) const {
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case TargetOpcode::COPY: {
1028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FPR64 copies will by lowered to ORR.16b
1029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (AArch64::FPR64RegClass.contains(DstReg) ||
1031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            AArch64::FPR128RegClass.contains(DstReg));
103285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
1033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ORRv16i8:
1034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
1035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(MI->getDesc().getNumOperands() == 3 && MI->getOperand(0).isReg() &&
1036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "invalid ORRv16i8 operands");
1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
1038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
104185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
104285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               int &FrameIndex) const {
1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
1049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBui:
1051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHui:
1052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() &&
1056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) {
1057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FrameIndex = MI->getOperand(1).getIndex();
1058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MI->getOperand(0).getReg();
1059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
106272062f5744557e270a38192554c3126ea5f97434Tim Northover
1063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 0;
106472062f5744557e270a38192554c3126ea5f97434Tim Northover}
106572062f5744557e270a38192554c3126ea5f97434Tim Northover
1066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              int &FrameIndex) const {
1068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBui:
1074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHui:
1075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() &&
1079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) {
1080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FrameIndex = MI->getOperand(1).getIndex();
1081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MI->getOperand(0).getReg();
1082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
108472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return 0;
1086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
108772062f5744557e270a38192554c3126ea5f97434Tim Northover
1088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Return true if this is load/store scales or extends its register offset.
1089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// This refers to scaling a dynamic index as opposed to scaled immediates.
1090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// MI should be a memory op that allows scaled addressing.
1091dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isScaledAddr(const MachineInstr *MI) const {
1092dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI->getOpcode()) {
1093dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1094dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBroW:
1096dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBroW:
1097dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDroW:
1098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHroW:
1099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHroW:
1100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQroW:
1101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWroW:
1102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXroW:
1103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWroW:
1104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXroW:
1105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWroW:
1106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSroW:
1107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWroW:
1108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXroW:
1109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBroW:
1110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBroW:
1111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDroW:
1112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHroW:
1113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHroW:
1114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQroW:
1115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSroW:
1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWroW:
1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXroW:
1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBroX:
1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBroX:
1120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDroX:
1121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHroX:
1122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHroX:
1123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQroX:
1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWroX:
1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXroX:
1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWroX:
1127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXroX:
1128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWroX:
1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSroX:
1130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWroX:
1131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXroX:
1132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBroX:
1133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBroX:
1134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDroX:
1135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHroX:
1136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHroX:
1137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQroX:
1138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSroX:
1139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWroX:
1140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXroX:
1141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val = MI->getOperand(3).getImm();
1143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getMemExtendType(Val);
1144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ExtType != AArch64_AM::UXTX) || AArch64_AM::getMemDoShift(Val);
1145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
114872062f5744557e270a38192554c3126ea5f97434Tim Northover
1149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Check all MachineMemOperands for a hint to suppress pairing.
1150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr *MI) const {
1151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits) &&
1152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Too many target MO flags");
1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (auto *MM : MI->memoperands()) {
1154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MM->getFlags() &
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        (MOSuppressPair << MachineMemOperand::MOTargetStartBit)) {
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
1157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
115872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
1160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
116172062f5744557e270a38192554c3126ea5f97434Tim Northover
1162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Set a flag on the first MachineMemOperand to suppress pairing.
1163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::suppressLdStPair(MachineInstr *MI) const {
1164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->memoperands_empty())
1165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
116672062f5744557e270a38192554c3126ea5f97434Tim Northover
1167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits) &&
1168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Too many target MO flags");
1169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  (*MI->memoperands_begin())
1170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ->setFlags(MOSuppressPair << MachineMemOperand::MOTargetStartBit);
1171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool
1174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64InstrInfo::getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
1175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       unsigned &Offset,
1176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       const TargetRegisterInfo *TRI) const {
1177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (LdSt->getOpcode()) {
1178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
1189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
1190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!LdSt->getOperand(1).isReg() || !LdSt->getOperand(2).isImm())
1191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BaseReg = LdSt->getOperand(1).getReg();
1193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineFunction &MF = *LdSt->getParent()->getParent();
1194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Width = getRegClass(LdSt->getDesc(), 0, TRI, MF)->getSize();
1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = LdSt->getOperand(2).getImm() * Width;
1196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
1197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
1198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
119972062f5744557e270a38192554c3126ea5f97434Tim Northover
1200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Detect opportunities for ldp/stp formation.
1201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines///
1202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Only called for LdSt for which getLdStBaseRegImmOfs returns true.
1203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::shouldClusterLoads(MachineInstr *FirstLdSt,
1204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          MachineInstr *SecondLdSt,
1205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          unsigned NumLoads) const {
1206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Only cluster up to a single pair.
1207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NumLoads > 1)
1208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (FirstLdSt->getOpcode() != SecondLdSt->getOpcode())
1210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // getLdStBaseRegImmOfs guarantees that oper 2 isImm.
1212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Ofs1 = FirstLdSt->getOperand(2).getImm();
1213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Allow 6 bits of positive range.
1214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Ofs1 > 64)
1215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The caller should already have ordered First/SecondLdSt by offset.
1217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Ofs2 = SecondLdSt->getOperand(2).getImm();
1218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Ofs1 + 1 == Ofs2;
1219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64InstrInfo::shouldScheduleAdjacent(MachineInstr *First,
1222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              MachineInstr *Second) const {
1223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Cyclone can fuse CMN, CMP followed by Bcc.
1224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: B0 can also fuse:
1226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // AND, BIC, ORN, ORR, or EOR (optional S) followed by Bcc or CBZ or CBNZ.
1227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Second->getOpcode() != AArch64::Bcc)
1228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (First->getOpcode()) {
1230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
1232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
1233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
1234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSWri:
1235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
1236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
1237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ANDSXri:
1238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
123972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
124072062f5744557e270a38192554c3126ea5f97434Tim Northover}
124172062f5744557e270a38192554c3126ea5f97434Tim Northover
1242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
1243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         int FrameIx,
1244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         uint64_t Offset,
1245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         const MDNode *MDPtr,
1246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         DebugLoc DL) const {
1247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE))
1248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addFrameIndex(FrameIx)
1249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addImm(0)
1250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addImm(Offset)
1251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                .addMetadata(MDPtr);
1252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return &*MIB;
125372062f5744557e270a38192554c3126ea5f97434Tim Northover}
125472062f5744557e270a38192554c3126ea5f97434Tim Northover
1255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const MachineInstrBuilder &AddSubReg(const MachineInstrBuilder &MIB,
1256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned Reg, unsigned SubIdx,
1257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned State,
1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            const TargetRegisterInfo *TRI) {
1259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!SubIdx)
1260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MIB.addReg(Reg, State);
126172062f5744557e270a38192554c3126ea5f97434Tim Northover
1262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TargetRegisterInfo::isPhysicalRegister(Reg))
1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MIB.addReg(Reg, State, SubIdx);
1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
126672062f5744557e270a38192554c3126ea5f97434Tim Northover
1267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg,
1268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        unsigned NumRegs) {
1269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We really want the positive remainder mod 32 here, that happens to be
1270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // easily obtainable with a mask.
1271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return ((DestReg - SrcReg) & 0x1f) < NumRegs;
1272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
127372062f5744557e270a38192554c3126ea5f97434Tim Northover
1274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::copyPhysRegTuple(
1275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL,
1276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode,
1277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm::ArrayRef<unsigned> Indices) const {
1278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  assert(Subtarget.hasNEON() &&
1279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Unexpected register copy without NEON");
1280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterInfo *TRI = &getRegisterInfo();
1281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
1282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
1283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumRegs = Indices.size();
1284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int SubReg = 0, End = NumRegs, Incr = 1;
1286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (forwardCopyWillClobberTuple(DestEncoding, SrcEncoding, NumRegs)) {
1287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SubReg = NumRegs - 1;
1288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    End = -1;
1289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Incr = -1;
1290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
129172062f5744557e270a38192554c3126ea5f97434Tim Northover
1292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (; SubReg != End; SubReg += Incr) {
1293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MachineInstrBuilder &MIB = BuildMI(MBB, I, DL, get(Opcode));
1294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI);
1295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI);
1296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI);
1297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
1301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   MachineBasicBlock::iterator I, DebugLoc DL,
1302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   unsigned DestReg, unsigned SrcReg,
1303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   bool KillSrc) const {
1304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR32spRegClass.contains(DestReg) &&
1305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (AArch64::GPR32spRegClass.contains(SrcReg) || SrcReg == AArch64::WZR)) {
1306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI = &getRegisterInfo();
1307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
1309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If either operand is WSP, expand to ADD #0.
1310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Subtarget.hasZeroCycleRegMove()) {
1311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Cyclone recognizes "ADD Xd, Xn, #0" as a zero-cycle register move.
1312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32,
1313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                     &AArch64::GPR64spRegClass);
1314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32,
1315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                    &AArch64::GPR64spRegClass);
1316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // This instruction is reading and writing X registers.  This may upset
1317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // the register scavenger and machine verifier, so we need to indicate
1318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // that we are reading an undefined value from SrcRegX, but a proper
1319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // value from SrcReg.
1320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestRegX)
1321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcRegX, RegState::Undef)
1322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(0)
1323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0))
1324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
1325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
1326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ADDWri), DestReg)
1327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, getKillRegState(KillSrc))
1328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(0)
1329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
133072062f5744557e270a38192554c3126ea5f97434Tim Northover      }
1331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroing()) {
1332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg).addImm(0).addImm(
1333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Subtarget.hasZeroCycleRegMove()) {
1336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Cyclone recognizes "ORR Xd, XZR, Xm" as a zero-cycle register move.
1337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32,
1338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                     &AArch64::GPR64spRegClass);
1339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32,
1340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                    &AArch64::GPR64spRegClass);
1341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // This instruction is reading and writing X registers.  This may upset
1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // the register scavenger and machine verifier, so we need to indicate
1343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // that we are reading an undefined value from SrcRegX, but a proper
1344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // value from SrcReg.
1345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestRegX)
1346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(AArch64::XZR)
1347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcRegX, RegState::Undef)
1348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
1349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
1350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Otherwise, expand to ORR WZR.
1351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BuildMI(MBB, I, DL, get(AArch64::ORRWrr), DestReg)
1352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(AArch64::WZR)
1353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .addReg(SrcReg, getKillRegState(KillSrc));
1354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
1355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
135872062f5744557e270a38192554c3126ea5f97434Tim Northover
1359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64spRegClass.contains(DestReg) &&
1360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) {
1361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DestReg == AArch64::SP || SrcReg == AArch64::SP) {
1362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If either operand is SP, expand to ADD #0.
1363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestReg)
1364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc))
1365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(0)
1366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroing()) {
1368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestReg).addImm(0).addImm(
1369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
1370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Otherwise, expand to ORR XZR.
1372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestReg)
1373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(AArch64::XZR)
1374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
137572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
137872062f5744557e270a38192554c3126ea5f97434Tim Northover
1379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DDDD register quad by copying the individual sub-registers.
1380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDDDRegClass.contains(DestReg) &&
1381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDDDRegClass.contains(SrcReg)) {
1382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::dsub2, AArch64::dsub3 };
1384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
138872062f5744557e270a38192554c3126ea5f97434Tim Northover
1389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DDD register triple by copying the individual sub-registers.
1390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDDRegClass.contains(DestReg) &&
1391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDDRegClass.contains(SrcReg)) {
1392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1,
1393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::dsub2 };
1394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
139872062f5744557e270a38192554c3126ea5f97434Tim Northover
1399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a DD register pair by copying the individual sub-registers.
1400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::DDRegClass.contains(DestReg) &&
1401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::DDRegClass.contains(SrcReg)) {
1402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1 };
1403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8,
1404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQQQ register quad by copying the individual sub-registers.
1409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQQQRegClass.contains(DestReg) &&
1410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQQQRegClass.contains(SrcReg)) {
1411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::qsub2, AArch64::qsub3 };
1413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQQ register triple by copying the individual sub-registers.
1419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQQRegClass.contains(DestReg) &&
1420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQQRegClass.contains(SrcReg)) {
1421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1,
1422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        AArch64::qsub2 };
1423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copy a QQ register pair by copying the individual sub-registers.
1429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::QQRegClass.contains(DestReg) &&
1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::QQRegClass.contains(SrcReg)) {
1431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1 };
1432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8,
1433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     Indices);
1434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
143672062f5744557e270a38192554c3126ea5f97434Tim Northover
1437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR128RegClass.contains(DestReg) &&
1438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR128RegClass.contains(SrcReg)) {
1439cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if(Subtarget.hasNEON()) {
1440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::STRQpre))
1445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP, RegState::Define)
1446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc))
1447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP)
1448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(-16);
1449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::LDRQpre))
1450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP, RegState::Define)
1451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(DestReg, RegState::Define)
1452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(AArch64::SP)
1453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(16);
145472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
145772062f5744557e270a38192554c3126ea5f97434Tim Northover
1458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.contains(DestReg) &&
1459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR64RegClass.contains(SrcReg)) {
1460cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if(Subtarget.hasNEON()) {
1461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub,
1462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub,
1464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVDr), DestReg)
1470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
147472062f5744557e270a38192554c3126ea5f97434Tim Northover
1475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR32RegClass.contains(DestReg) &&
1476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.contains(SrcReg)) {
1477cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if(Subtarget.hasNEON()) {
1478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub,
1479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub,
1481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
149172062f5744557e270a38192554c3126ea5f97434Tim Northover
1492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR16RegClass.contains(DestReg) &&
1493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR16RegClass.contains(SrcReg)) {
1494cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if(Subtarget.hasNEON()) {
1495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub,
1504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR32RegClass);
1505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub,
1506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR32RegClass);
1507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
151272062f5744557e270a38192554c3126ea5f97434Tim Northover
1513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR8RegClass.contains(DestReg) &&
1514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR8RegClass.contains(SrcReg)) {
1515cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if(Subtarget.hasNEON()) {
1516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR128RegClass);
1518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR128RegClass);
1520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg)
1521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg)
1522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
1523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub,
1525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       &AArch64::FPR32RegClass);
1526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub,
1527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      &AArch64::FPR32RegClass);
1528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg)
1529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addReg(SrcReg, getKillRegState(KillSrc));
153072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copies between GPR64 and FPR64.
1535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR64RegClass.contains(DestReg) &&
1536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR64RegClass.contains(SrcReg)) {
1537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVXDr), DestReg)
1538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR64RegClass.contains(DestReg) &&
1542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR64RegClass.contains(SrcReg)) {
1543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVDXr), DestReg)
1544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Copies between GPR32 and FPR32.
1548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::FPR32RegClass.contains(DestReg) &&
1549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::GPR32RegClass.contains(SrcReg)) {
1550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVWSr), DestReg)
1551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (AArch64::GPR32RegClass.contains(DestReg) &&
1555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64::FPR32RegClass.contains(SrcReg)) {
1556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVSWr), DestReg)
1557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg, getKillRegState(KillSrc));
1558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
156072062f5744557e270a38192554c3126ea5f97434Tim Northover
1561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (DestReg == AArch64::NZCV) {
1562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy");
1563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::MSR))
1564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64SysReg::NZCV)
1565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcReg, getKillRegState(KillSrc))
1566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define);
1567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SrcReg == AArch64::NZCV) {
1571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy");
1572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, I, DL, get(AArch64::MRS))
1573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(DestReg)
1574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64SysReg::NZCV)
1575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc));
1576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("unimplemented reg-to-reg copy");
1580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::storeRegToStackSlot(
1583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg,
1584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isKill, int FI, const TargetRegisterClass *RC,
1585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI) const {
1586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DebugLoc DL;
1587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MBBI != MBB.end())
1588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DL = MBBI->getDebugLoc();
1589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction &MF = *MBB.getParent();
1590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFrameInfo &MFI = *MF.getFrameInfo();
1591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Align = MFI.getObjectAlignment(FI);
1592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachinePointerInfo PtrInfo(PseudoSourceValue::getFixedStack(FI));
1594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineMemOperand *MMO = MF.getMachineMemOperand(
1595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PtrInfo, MachineMemOperand::MOStore, MFI.getObjectSize(FI), Align);
1596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
1597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Offset = true;
1598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RC->getSize()) {
1599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1:
1600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRBui;
1602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2:
1604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRHui;
1606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4:
1608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRWui;
1610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(SrcReg))
1611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR32RegClass);
1612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(SrcReg != AArch64::WSP);
1614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRSui;
1616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 8:
1618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRXui;
1620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(SrcReg))
1621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass);
1622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(SrcReg != AArch64::SP);
1624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRDui;
1626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 16:
1628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::STRQui;
1630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1631cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Twov1d, Offset = false;
1634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 24:
1637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Threev1d, Offset = false;
1641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 32:
1644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1645cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Fourv1d, Offset = false;
1648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Twov2d, Offset = false;
165272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 48:
1655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1656cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1657dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Threev2d, Offset = false;
1659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 64:
1662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1663cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register store without NEON");
1665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::ST1Fourv2d, Offset = false;
1666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && "Unknown register class");
1670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstrBuilder &MI = BuildMI(MBB, MBBI, DL, get(Opc))
1672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addReg(SrcReg, getKillRegState(isKill))
1673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addFrameIndex(FI);
1674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset)
1676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.addImm(0);
1677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI.addMemOperand(MMO);
1678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::loadRegFromStackSlot(
1681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg,
1682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int FI, const TargetRegisterClass *RC,
1683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const TargetRegisterInfo *TRI) const {
1684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DebugLoc DL;
1685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MBBI != MBB.end())
1686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DL = MBBI->getDebugLoc();
1687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFunction &MF = *MBB.getParent();
1688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineFrameInfo &MFI = *MF.getFrameInfo();
1689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Align = MFI.getObjectAlignment(FI);
1690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachinePointerInfo PtrInfo(PseudoSourceValue::getFixedStack(FI));
1691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineMemOperand *MMO = MF.getMachineMemOperand(
1692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PtrInfo, MachineMemOperand::MOLoad, MFI.getObjectSize(FI), Align);
169372062f5744557e270a38192554c3126ea5f97434Tim Northover
1694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = 0;
1695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Offset = true;
1696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RC->getSize()) {
1697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1:
1698dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR8RegClass.hasSubClassEq(RC))
1699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRBui;
1700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2:
1702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR16RegClass.hasSubClassEq(RC))
1703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRHui;
1704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4:
1706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) {
1707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRWui;
1708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(DestReg))
1709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR32RegClass);
1710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(DestReg != AArch64::WSP);
1712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR32RegClass.hasSubClassEq(RC))
1713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRSui;
1714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 8:
1716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) {
1717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRXui;
1718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (TargetRegisterInfo::isVirtualRegister(DestReg))
1719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR64RegClass);
1720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else
1721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(DestReg != AArch64::SP);
1722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::FPR64RegClass.hasSubClassEq(RC))
1723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRDui;
1724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 16:
1726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::FPR128RegClass.hasSubClassEq(RC))
1727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LDRQui;
1728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (AArch64::DDRegClass.hasSubClassEq(RC)) {
1729cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Twov1d, Offset = false;
173272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
1733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 24:
1735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDRegClass.hasSubClassEq(RC)) {
1736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Threev1d, Offset = false;
1739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 32:
1742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::DDDDRegClass.hasSubClassEq(RC)) {
1743cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Fourv1d, Offset = false;
1746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (AArch64::QQRegClass.hasSubClassEq(RC)) {
1747cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Twov2d, Offset = false;
1750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 48:
1753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQRegClass.hasSubClassEq(RC)) {
1754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Threev2d, Offset = false;
1757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 64:
1760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64::QQQQRegClass.hasSubClassEq(RC)) {
1761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      assert(Subtarget.hasNEON() &&
1762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected register load without NEON");
1763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::LD1Fourv2d, Offset = false;
1764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Opc && "Unknown register class");
1768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachineInstrBuilder &MI = BuildMI(MBB, MBBI, DL, get(Opc))
1770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addReg(DestReg, getDefRegState(true))
1771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      .addFrameIndex(FI);
1772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset)
1773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.addImm(0);
1774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI.addMemOperand(MMO);
1775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid llvm::emitFrameOffset(MachineBasicBlock &MBB,
1778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           MachineBasicBlock::iterator MBBI, DebugLoc DL,
1779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           unsigned DestReg, unsigned SrcReg, int Offset,
1780cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           const TargetInstrInfo *TII,
1781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           MachineInstr::MIFlag Flag, bool SetNZCV) {
1782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (DestReg == SrcReg && Offset == 0)
1783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSub = Offset < 0;
1786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isSub)
1787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = -Offset;
1788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: If the offset won't fit in 24-bits, compute the offset into a
1790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // scratch register.  If DestReg is a virtual register, use it as the
1791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // scratch register; otherwise, create a new virtual register (to be
1792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // replaced by the scavenger at the end of PEI).  That case can be optimized
1793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // slightly if DestReg is SP which is always 16-byte aligned, so the scratch
1794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // register can be loaded with offset%8 and the add/sub can use an extending
1795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // instruction with LSL#3.
1796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Currently the function handles any offsets but generates a poor sequence
1797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // of code.
1798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //  assert(Offset < (1 << 24) && "unimplemented reg plus immediate");
1799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc;
1801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SetNZCV)
1802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri;
1803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else
1804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri;
1805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned MaxEncoding = 0xfff;
1806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned ShiftSize = 12;
1807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned MaxEncodableValue = MaxEncoding << ShiftSize;
1808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (((unsigned)Offset) >= (1 << ShiftSize)) {
1809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ThisVal;
1810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (((unsigned)Offset) > MaxEncodableValue) {
1811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ThisVal = MaxEncodableValue;
1812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
1813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ThisVal = Offset & MaxEncodableValue;
1814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert((ThisVal >> ShiftSize) <= MaxEncoding &&
1816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Encoding cannot handle value that big");
1817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
1818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg)
1819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(ThisVal >> ShiftSize)
1820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftSize))
1821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .setMIFlag(Flag);
1822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = DestReg;
1824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset -= ThisVal;
1825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Offset == 0)
1826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
1829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcReg)
1830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(Offset)
1831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0))
1832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .setMIFlag(Flag);
183372062f5744557e270a38192554c3126ea5f97434Tim Northover}
183472062f5744557e270a38192554c3126ea5f97434Tim Northover
1835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMachineInstr *
1836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
1837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        const SmallVectorImpl<unsigned> &Ops,
1838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        int FrameIndex) const {
1839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This is a bit of a hack. Consider this instruction:
1840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //   %vreg0<def> = COPY %SP; GPR64all:%vreg0
1842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We explicitly chose GPR64all for the virtual register so such a copy might
1844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // be eliminated by RegisterCoalescer. However, that may not be possible, and
1845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // %vreg0 may even spill. We can't spill %SP, and since it is in the GPR64all
1846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // register class, TargetInstrInfo::foldMemoryOperand() is going to try.
1847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // To prevent that, we are going to constrain the %vreg0 register class here.
1849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // <rdar://problem/11522048>
1851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
1852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MI->isCopy()) {
1853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned DstReg = MI->getOperand(0).getReg();
1854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SrcReg = MI->getOperand(1).getReg();
1855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SrcReg == AArch64::SP &&
1856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TargetRegisterInfo::isVirtualRegister(DstReg)) {
1857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MF.getRegInfo().constrainRegClass(DstReg, &AArch64::GPR64RegClass);
1858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
1859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DstReg == AArch64::SP &&
1861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TargetRegisterInfo::isVirtualRegister(SrcReg)) {
1862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass);
1863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
1864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Cannot fold.
1868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
1869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesint llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
1872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    bool *OutUseUnscaledOp,
1873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned *OutUnscaledOp,
1874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    int *EmittableOffset) {
1875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Scale = 1;
1876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsSigned = false;
1877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The ImmIdx should be changed case by case if it is not 2.
1878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ImmIdx = 2;
1879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned UnscaledOp = 0;
1880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Set output values in case of early exit.
1881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (EmittableOffset)
1882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *EmittableOffset = 0;
1883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUseUnscaledOp)
1884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUseUnscaledOp = false;
1885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUnscaledOp)
1886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUnscaledOp = 0;
1887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MI.getOpcode()) {
1888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
1889cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    llvm_unreachable("unhandled opcode in rewriteAArch64FrameIndex");
1890dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Vector spills/fills can't take an immediate offset.
1891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Twov2d:
1892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Threev2d:
1893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Fourv2d:
1894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Twov1d:
1895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Threev1d:
1896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LD1Fourv1d:
1897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Twov2d:
1898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Threev2d:
1899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Fourv2d:
1900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Twov1d:
1901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Threev1d:
1902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ST1Fourv1d:
1903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64FrameOffsetCannotUpdate;
1904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::PRFMui:
1905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::PRFUMi;
1907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXui:
1909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURXi;
1911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWui:
1913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURWi;
1915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBui:
1917dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURBi;
1919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHui:
1921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURHi;
1923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSui:
1925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSi;
1927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRDui:
1929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURDi;
1931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRQui:
1933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
1934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURQi;
1935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBui:
1937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURBBi;
1939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHui:
1941dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURHHi;
1943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXui:
1945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSBXi;
1947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWui:
1949dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSBWi;
1951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXui:
1953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSHXi;
1955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWui:
1957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSHWi;
1959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWui:
1961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::LDURSWi;
1963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXui:
1966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURXi;
1968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWui:
1970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURWi;
1972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBui:
1974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURBi;
1976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHui:
1978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURHi;
1980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRSui:
1982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
1983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURSi;
1984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRDui:
1986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
1987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURDi;
1988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRQui:
1990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
1991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURQi;
1992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBui:
1994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
1995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURBBi;
1996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHui:
1998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 2;
1999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    UnscaledOp = AArch64::STURHHi;
2000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
2001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPXi:
2003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPDi:
2004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPXi:
2005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPDi:
2006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
2007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 8;
2008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
2009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPQi:
2010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPQi:
2011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
2012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 16;
2013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
2014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPWi:
2015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSi:
2016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPWi:
2017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPSi:
2018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
2019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 4;
2020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
2021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURXi:
2023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURWi:
2024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURBi:
2025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURHi:
2026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSi:
2027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURDi:
2028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURQi:
2029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURHHi:
2030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURBBi:
2031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSBXi:
2032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSBWi:
2033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSHXi:
2034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSHWi:
2035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDURSWi:
2036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURXi:
2037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURWi:
2038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURBi:
2039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURHi:
2040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURSi:
2041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURDi:
2042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURQi:
2043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURBBi:
2044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STURHHi:
2045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
2046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
2047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Offset += MI.getOperand(ImmIdx).getImm() * Scale;
2050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool useUnscaledOp = false;
2052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the offset doesn't match the scale, we rewrite the instruction to
2053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // use the unscaled instruction instead. Likewise, if we have a negative
2054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // offset (and have an unscaled op to use).
2055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0))
2056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    useUnscaledOp = true;
2057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Use an unscaled addressing mode if the instruction has a negative offset
2059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // (or if the instruction is already using an unscaled addressing mode).
2060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned MaskBits;
2061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsSigned) {
2062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // ldp/stp instructions.
2063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 7;
2064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset /= Scale;
2065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (UnscaledOp == 0 || useUnscaledOp) {
2066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 9;
2067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = true;
2068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Scale = 1;
2069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
2070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaskBits = 12;
2071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsSigned = false;
2072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset /= Scale;
2073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Attempt to fold address computation.
2076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int MaxOff = (1 << (MaskBits - IsSigned)) - 1;
2077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int MinOff = (IsSigned ? (-MaxOff - 1) : 0);
2078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Offset >= MinOff && Offset <= MaxOff) {
2079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (EmittableOffset)
2080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      *EmittableOffset = Offset;
2081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = 0;
2082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
2083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int NewOff = Offset < 0 ? MinOff : MaxOff;
2084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (EmittableOffset)
2085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      *EmittableOffset = NewOff;
2086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = (Offset - NewOff) * Scale;
2087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUseUnscaledOp)
2089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUseUnscaledOp = useUnscaledOp;
2090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OutUnscaledOp)
2091dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutUnscaledOp = UnscaledOp;
2092dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return AArch64FrameOffsetCanUpdate |
2093dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         (Offset == 0 ? AArch64FrameOffsetIsLegal : 0);
2094dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2096dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
2097dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    unsigned FrameReg, int &Offset,
2098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    const AArch64InstrInfo *TII) {
2099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opcode = MI.getOpcode();
2100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ImmIdx = FrameRegIdx + 1;
2101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) {
2103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset += MI.getOperand(ImmIdx).getImm();
2104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(),
2105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    MI.getOperand(0).getReg(), FrameReg, Offset, TII,
2106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri));
2107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.eraseFromParent();
2108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Offset = 0;
2109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int NewOffset;
2113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned UnscaledOp;
2114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool UseUnscaledOp;
2115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int Status = isAArch64FrameOffsetLegal(MI, Offset, &UseUnscaledOp,
2116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         &UnscaledOp, &NewOffset);
2117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Status & AArch64FrameOffsetCanUpdate) {
2118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Status & AArch64FrameOffsetIsLegal)
2119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Replace the FrameIndex with FrameReg.
2120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
2121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (UseUnscaledOp)
2122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MI.setDesc(TII->get(UnscaledOp));
2123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MI.getOperand(ImmIdx).ChangeToImmediate(NewOffset);
2125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Offset == 0;
2126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
2132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  NopInst.setOpcode(AArch64::HINT);
2133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  NopInst.addOperand(MCOperand::CreateImm(0));
2134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2135