AArch64InstrInfo.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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 "AArch64.h"
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64InstrInfo.h"
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MachineFunctionInfo.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64TargetMachine.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCTargetDesc.h"
1919254c49a8752fe8c6fa648a6eb29f20a1f62c8bTim Northover#include "Utils/AArch64BaseInfo.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineConstantPool.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineDominators.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFrameInfo.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFunctionPass.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineInstrBuilder.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineRegisterInfo.h"
2672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/IR/Function.h"
2772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
2972062f5744557e270a38192554c3126ea5f97434Tim Northover#include <algorithm>
3072062f5744557e270a38192554c3126ea5f97434Tim Northover
31354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka#define GET_INSTRINFO_CTOR_DTOR
3272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenInstrInfo.inc"
3372062f5744557e270a38192554c3126ea5f97434Tim Northover
3472062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3572062f5744557e270a38192554c3126ea5f97434Tim Northover
3672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI)
3772062f5744557e270a38192554c3126ea5f97434Tim Northover  : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP),
384393f48c03300203594e22d248808f20dd59d886Bill Wendling    Subtarget(STI) {}
3972062f5744557e270a38192554c3126ea5f97434Tim Northover
4072062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
4172062f5744557e270a38192554c3126ea5f97434Tim Northover                                   MachineBasicBlock::iterator I, DebugLoc DL,
4272062f5744557e270a38192554c3126ea5f97434Tim Northover                                   unsigned DestReg, unsigned SrcReg,
4372062f5744557e270a38192554c3126ea5f97434Tim Northover                                   bool KillSrc) const {
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opc = 0;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned ZeroReg = 0;
4672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (DestReg == AArch64::XSP || SrcReg == AArch64::XSP) {
4772062f5744557e270a38192554c3126ea5f97434Tim Northover    // E.g. ADD xDst, xsp, #0 (, lsl #0)
4872062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, I, DL, get(AArch64::ADDxxi_lsl0_s), DestReg)
4972062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg)
5072062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(0);
5172062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
5272062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
5372062f5744557e270a38192554c3126ea5f97434Tim Northover    // E.g. ADD wDST, wsp, #0 (, lsl #0)
5472062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, I, DL, get(AArch64::ADDwwi_lsl0_s), DestReg)
5572062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg)
5672062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(0);
5772062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
5872062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (DestReg == AArch64::NZCV) {
5972062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(AArch64::GPR64RegClass.contains(SrcReg));
6072062f5744557e270a38192554c3126ea5f97434Tim Northover    // E.g. MSR NZCV, xDST
6172062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, I, DL, get(AArch64::MSRix))
6272062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(A64SysReg::NZCV)
6372062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg);
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (SrcReg == AArch64::NZCV) {
6572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(AArch64::GPR64RegClass.contains(DestReg));
6672062f5744557e270a38192554c3126ea5f97434Tim Northover    // E.g. MRS xDST, NZCV
6772062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, I, DL, get(AArch64::MRSxi), DestReg)
6872062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(A64SysReg::NZCV);
6972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (AArch64::GPR64RegClass.contains(DestReg)) {
70e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    if(AArch64::GPR64RegClass.contains(SrcReg)){
71e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      Opc = AArch64::ORRxxx_lsl;
72e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      ZeroReg = AArch64::XZR;
73e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    } else{
74e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      assert(AArch64::FPR64RegClass.contains(SrcReg));
75e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVxd), DestReg)
76e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
77e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
78e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
7972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (AArch64::GPR32RegClass.contains(DestReg)) {
80e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    if(AArch64::GPR32RegClass.contains(SrcReg)){
81e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      Opc = AArch64::ORRwww_lsl;
82e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      ZeroReg = AArch64::WZR;
83e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    } else{
84e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      assert(AArch64::FPR32RegClass.contains(SrcReg));
85e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVws), DestReg)
86e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
87e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
88e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
8972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (AArch64::FPR32RegClass.contains(DestReg)) {
90e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    if(AArch64::FPR32RegClass.contains(SrcReg)){
91e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVss), DestReg)
92e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
93e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
94e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
95e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    else {
96e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      assert(AArch64::GPR32RegClass.contains(SrcReg));
97e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVsw), DestReg)
98e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
99e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
100e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
10172062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (AArch64::FPR64RegClass.contains(DestReg)) {
102e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    if(AArch64::FPR64RegClass.contains(SrcReg)){
103e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVdd), DestReg)
104e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
105e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
106e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
107e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    else {
108e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      assert(AArch64::GPR64RegClass.contains(SrcReg));
109e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      BuildMI(MBB, I, DL, get(AArch64::FMOVdx), DestReg)
110e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin        .addReg(SrcReg);
111e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin      return;
112e54360be01d1eaccd5ef27f510634927aaa887a4Kevin Qin    }
11372062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (AArch64::FPR128RegClass.contains(DestReg)) {
11472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(AArch64::FPR128RegClass.contains(SrcReg));
11572062f5744557e270a38192554c3126ea5f97434Tim Northover
116e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling    // If NEON is enable, we use ORR to implement this copy.
117e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling    // If NEON isn't available, emit STR and LDR to handle this.
118e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling    if(getSubTarget().hasNEON()) {
119e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling      BuildMI(MBB, I, DL, get(AArch64::ORRvvv_16B), DestReg)
120e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(SrcReg)
121e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(SrcReg);
122e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling      return;
123e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling    } else {
124e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling      BuildMI(MBB, I, DL, get(AArch64::LSFP128_PreInd_STR), AArch64::XSP)
125e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(SrcReg)
126e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(AArch64::XSP)
127e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addImm(0x1ff & -16);
12872062f5744557e270a38192554c3126ea5f97434Tim Northover
129e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling      BuildMI(MBB, I, DL, get(AArch64::LSFP128_PostInd_LDR), DestReg)
130e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(AArch64::XSP, RegState::Define)
131e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addReg(AArch64::XSP)
132e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling        .addImm(16);
133e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling      return;
134e40ef6a9fc96c74f7df5681a070246ea990499ebBill Wendling    }
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR8RegClass.contains(DestReg, SrcReg)) {
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The copy of two FPR8 registers is implemented by the copy of two FPR32
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const TargetRegisterInfo *TRI = &getRegisterInfo();
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Dst = TRI->getMatchingSuperReg(DestReg, AArch64::sub_8,
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            &AArch64::FPR32RegClass);
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Src = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_8,
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            &AArch64::FPR32RegClass);
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVss), Dst)
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src);
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR16RegClass.contains(DestReg, SrcReg)) {
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The copy of two FPR16 registers is implemented by the copy of two FPR32
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const TargetRegisterInfo *TRI = &getRegisterInfo();
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Dst = TRI->getMatchingSuperReg(DestReg, AArch64::sub_16,
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            &AArch64::FPR32RegClass);
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Src = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_16,
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            &AArch64::FPR32RegClass);
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(MBB, I, DL, get(AArch64::FMOVss), Dst)
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src);
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
15572062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CopyPhysRegTuple(MBB, I, DL, DestReg, SrcReg);
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
15872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
15972062f5744557e270a38192554c3126ea5f97434Tim Northover
16072062f5744557e270a38192554c3126ea5f97434Tim Northover  // E.g. ORR xDst, xzr, xSrc, lsl #0
16172062f5744557e270a38192554c3126ea5f97434Tim Northover  BuildMI(MBB, I, DL, get(Opc), DestReg)
16272062f5744557e270a38192554c3126ea5f97434Tim Northover    .addReg(ZeroReg)
16372062f5744557e270a38192554c3126ea5f97434Tim Northover    .addReg(SrcReg)
16472062f5744557e270a38192554c3126ea5f97434Tim Northover    .addImm(0);
16572062f5744557e270a38192554c3126ea5f97434Tim Northover}
16672062f5744557e270a38192554c3126ea5f97434Tim Northover
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid AArch64InstrInfo::CopyPhysRegTuple(MachineBasicBlock &MBB,
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        MachineBasicBlock::iterator I,
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        DebugLoc DL, unsigned DestReg,
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        unsigned SrcReg) const {
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SubRegs;
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool IsQRegs;
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (AArch64::DPairRegClass.contains(DestReg, SrcReg)) {
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 2;
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = false;
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::DTripleRegClass.contains(DestReg, SrcReg)) {
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 3;
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = false;
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::DQuadRegClass.contains(DestReg, SrcReg)) {
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 4;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = false;
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::QPairRegClass.contains(DestReg, SrcReg)) {
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 2;
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = true;
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::QTripleRegClass.contains(DestReg, SrcReg)) {
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 3;
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = true;
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::QQuadRegClass.contains(DestReg, SrcReg)) {
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SubRegs = 4;
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IsQRegs = true;
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Unknown register class");
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned BeginIdx = IsQRegs ? AArch64::qsub_0 : AArch64::dsub_0;
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int Spacing = 1;
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const TargetRegisterInfo *TRI = &getRegisterInfo();
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Copy register tuples backward when the first Dest reg overlaps
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // with SrcReg.
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (TRI->regsOverlap(SrcReg, TRI->getSubReg(DestReg, BeginIdx))) {
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BeginIdx = BeginIdx + (SubRegs - 1);
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Spacing = -1;
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc = IsQRegs ? AArch64::ORRvvv_16B : AArch64::ORRvvv_8B;
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i != SubRegs; ++i) {
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i * Spacing);
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i * Spacing);
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(Dst && Src && "Bad sub-register");
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst)
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(Src)
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(Src);
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return;
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21672062f5744557e270a38192554c3126ea5f97434Tim Northover/// Does the Opcode represent a conditional branch that we can remove and re-add
21772062f5744557e270a38192554c3126ea5f97434Tim Northover/// at the end of a basic block?
21872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic bool isCondBranch(unsigned Opc) {
21972062f5744557e270a38192554c3126ea5f97434Tim Northover  return Opc == AArch64::Bcc || Opc == AArch64::CBZw || Opc == AArch64::CBZx ||
22072062f5744557e270a38192554c3126ea5f97434Tim Northover         Opc == AArch64::CBNZw || Opc == AArch64::CBNZx ||
22172062f5744557e270a38192554c3126ea5f97434Tim Northover         Opc == AArch64::TBZwii || Opc == AArch64::TBZxii ||
22272062f5744557e270a38192554c3126ea5f97434Tim Northover         Opc == AArch64::TBNZwii || Opc == AArch64::TBNZxii;
22372062f5744557e270a38192554c3126ea5f97434Tim Northover}
22472062f5744557e270a38192554c3126ea5f97434Tim Northover
22572062f5744557e270a38192554c3126ea5f97434Tim Northover/// Takes apart a given conditional branch MachineInstr (see isCondBranch),
22672062f5744557e270a38192554c3126ea5f97434Tim Northover/// setting TBB to the destination basic block and populating the Cond vector
22772062f5744557e270a38192554c3126ea5f97434Tim Northover/// with data necessary to recreate the conditional branch at a later
22872062f5744557e270a38192554c3126ea5f97434Tim Northover/// date. First element will be the opcode, and subsequent ones define the
22972062f5744557e270a38192554c3126ea5f97434Tim Northover/// conditions being branched on in an instruction-specific manner.
23072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic void classifyCondBranch(MachineInstr *I, MachineBasicBlock *&TBB,
23172062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MachineOperand> &Cond) {
23272062f5744557e270a38192554c3126ea5f97434Tim Northover  switch(I->getOpcode()) {
23372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::Bcc:
23472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBZw:
23572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBZx:
23672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBNZw:
23772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBNZx:
23872062f5744557e270a38192554c3126ea5f97434Tim Northover    // These instructions just have one predicate operand in position 0 (either
23972062f5744557e270a38192554c3126ea5f97434Tim Northover    // a condition code or a register being compared).
24072062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
24172062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond.push_back(I->getOperand(0));
24272062f5744557e270a38192554c3126ea5f97434Tim Northover    TBB = I->getOperand(1).getMBB();
24372062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
24472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBZwii:
24572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBZxii:
24672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBNZwii:
24772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBNZxii:
24872062f5744557e270a38192554c3126ea5f97434Tim Northover    // These have two predicate operands: a register and a bit position.
24972062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
25072062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond.push_back(I->getOperand(0));
25172062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond.push_back(I->getOperand(1));
25272062f5744557e270a38192554c3126ea5f97434Tim Northover    TBB = I->getOperand(2).getMBB();
25372062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
25472062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
25572062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Unknown conditional branch to classify");
25672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
25772062f5744557e270a38192554c3126ea5f97434Tim Northover}
25872062f5744557e270a38192554c3126ea5f97434Tim Northover
25972062f5744557e270a38192554c3126ea5f97434Tim Northover
26072062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
26172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
26272062f5744557e270a38192554c3126ea5f97434Tim Northover                                MachineBasicBlock *&FBB,
26372062f5744557e270a38192554c3126ea5f97434Tim Northover                                SmallVectorImpl<MachineOperand> &Cond,
26472062f5744557e270a38192554c3126ea5f97434Tim Northover                                bool AllowModify) const {
26572062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block has no terminators, it just falls into the block after it.
26672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
26772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin())
26872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
26972062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
27072062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
27172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
27272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
27372062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
27472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
27572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!isUnpredicatedTerminator(I))
27672062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
27772062f5744557e270a38192554c3126ea5f97434Tim Northover
27872062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the last instruction in the block.
27972062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *LastInst = I;
28072062f5744557e270a38192554c3126ea5f97434Tim Northover
28172062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there is only one terminator instruction, process it.
28272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned LastOpc = LastInst->getOpcode();
28372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
28472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (LastOpc == AArch64::Bimm) {
28572062f5744557e270a38192554c3126ea5f97434Tim Northover      TBB = LastInst->getOperand(0).getMBB();
28672062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
28772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
28872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isCondBranch(LastOpc)) {
28972062f5744557e270a38192554c3126ea5f97434Tim Northover      classifyCondBranch(LastInst, TBB, Cond);
29072062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
29172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
29272062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;  // Can't handle indirect branch.
29372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
29472062f5744557e270a38192554c3126ea5f97434Tim Northover
29572062f5744557e270a38192554c3126ea5f97434Tim Northover  // Get the instruction before it if it is a terminator.
29672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr *SecondLastInst = I;
29772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned SecondLastOpc = SecondLastInst->getOpcode();
29872062f5744557e270a38192554c3126ea5f97434Tim Northover
29972062f5744557e270a38192554c3126ea5f97434Tim Northover  // If AllowModify is true and the block ends with two or more unconditional
30072062f5744557e270a38192554c3126ea5f97434Tim Northover  // branches, delete all but the first unconditional branch.
30172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (AllowModify && LastOpc == AArch64::Bimm) {
30272062f5744557e270a38192554c3126ea5f97434Tim Northover    while (SecondLastOpc == AArch64::Bimm) {
30372062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst->eraseFromParent();
30472062f5744557e270a38192554c3126ea5f97434Tim Northover      LastInst = SecondLastInst;
30572062f5744557e270a38192554c3126ea5f97434Tim Northover      LastOpc = LastInst->getOpcode();
30672062f5744557e270a38192554c3126ea5f97434Tim Northover      if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
30772062f5744557e270a38192554c3126ea5f97434Tim Northover        // Return now the only terminator is an unconditional branch.
30872062f5744557e270a38192554c3126ea5f97434Tim Northover        TBB = LastInst->getOperand(0).getMBB();
30972062f5744557e270a38192554c3126ea5f97434Tim Northover        return false;
31072062f5744557e270a38192554c3126ea5f97434Tim Northover      } else {
31172062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastInst = I;
31272062f5744557e270a38192554c3126ea5f97434Tim Northover        SecondLastOpc = SecondLastInst->getOpcode();
31372062f5744557e270a38192554c3126ea5f97434Tim Northover      }
31472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
31572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
31672062f5744557e270a38192554c3126ea5f97434Tim Northover
31772062f5744557e270a38192554c3126ea5f97434Tim Northover  // If there are three terminators, we don't know what sort of block this is.
31872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
31972062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
32072062f5744557e270a38192554c3126ea5f97434Tim Northover
32172062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with a B and a Bcc, handle it.
32272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (LastOpc == AArch64::Bimm) {
32372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (SecondLastOpc == AArch64::Bcc) {
32472062f5744557e270a38192554c3126ea5f97434Tim Northover      TBB =  SecondLastInst->getOperand(1).getMBB();
32572062f5744557e270a38192554c3126ea5f97434Tim Northover      Cond.push_back(MachineOperand::CreateImm(AArch64::Bcc));
32672062f5744557e270a38192554c3126ea5f97434Tim Northover      Cond.push_back(SecondLastInst->getOperand(0));
32772062f5744557e270a38192554c3126ea5f97434Tim Northover      FBB = LastInst->getOperand(0).getMBB();
32872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
32972062f5744557e270a38192554c3126ea5f97434Tim Northover    } else if (isCondBranch(SecondLastOpc)) {
33072062f5744557e270a38192554c3126ea5f97434Tim Northover      classifyCondBranch(SecondLastInst, TBB, Cond);
33172062f5744557e270a38192554c3126ea5f97434Tim Northover      FBB = LastInst->getOperand(0).getMBB();
33272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
33372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
33472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
33572062f5744557e270a38192554c3126ea5f97434Tim Northover
33672062f5744557e270a38192554c3126ea5f97434Tim Northover  // If the block ends with two unconditional branches, handle it.  The second
33772062f5744557e270a38192554c3126ea5f97434Tim Northover  // one is not executed, so remove it.
33872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) {
33972062f5744557e270a38192554c3126ea5f97434Tim Northover    TBB = SecondLastInst->getOperand(0).getMBB();
34072062f5744557e270a38192554c3126ea5f97434Tim Northover    I = LastInst;
34172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (AllowModify)
34272062f5744557e270a38192554c3126ea5f97434Tim Northover      I->eraseFromParent();
34372062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
34472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
34572062f5744557e270a38192554c3126ea5f97434Tim Northover
34672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise, can't handle this.
34772062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
34872062f5744557e270a38192554c3126ea5f97434Tim Northover}
34972062f5744557e270a38192554c3126ea5f97434Tim Northover
35072062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64InstrInfo::ReverseBranchCondition(
35172062f5744557e270a38192554c3126ea5f97434Tim Northover                                  SmallVectorImpl<MachineOperand> &Cond) const {
35272062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Cond[0].getImm()) {
35372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::Bcc: {
35472062f5744557e270a38192554c3126ea5f97434Tim Northover    A64CC::CondCodes CC = static_cast<A64CC::CondCodes>(Cond[1].getImm());
35572062f5744557e270a38192554c3126ea5f97434Tim Northover    CC = A64InvertCondCode(CC);
35672062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[1].setImm(CC);
35772062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
35872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
35972062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBZw:
36072062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::CBNZw);
36172062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
36272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBZx:
36372062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::CBNZx);
36472062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
36572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBNZw:
36672062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::CBZw);
36772062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
36872062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::CBNZx:
36972062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::CBZx);
37072062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
37172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBZwii:
37272062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::TBNZwii);
37372062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
37472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBZxii:
37572062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::TBNZxii);
37672062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
37772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBNZwii:
37872062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::TBZwii);
37972062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
38072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TBNZxii:
38172062f5744557e270a38192554c3126ea5f97434Tim Northover    Cond[0].setImm(AArch64::TBZxii);
38272062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
38372062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
38472062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Unknown branch type");
38572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38672062f5744557e270a38192554c3126ea5f97434Tim Northover}
38772062f5744557e270a38192554c3126ea5f97434Tim Northover
38872062f5744557e270a38192554c3126ea5f97434Tim Northover
38972062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned
39072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
39172062f5744557e270a38192554c3126ea5f97434Tim Northover                               MachineBasicBlock *FBB,
39272062f5744557e270a38192554c3126ea5f97434Tim Northover                               const SmallVectorImpl<MachineOperand> &Cond,
39372062f5744557e270a38192554c3126ea5f97434Tim Northover                               DebugLoc DL) const {
39472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (FBB == 0 && Cond.empty()) {
39572062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(TBB);
39672062f5744557e270a38192554c3126ea5f97434Tim Northover    return 1;
39772062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (FBB == 0) {
39872062f5744557e270a38192554c3126ea5f97434Tim Northover    MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
39972062f5744557e270a38192554c3126ea5f97434Tim Northover    for (int i = 1, e = Cond.size(); i != e; ++i)
40072062f5744557e270a38192554c3126ea5f97434Tim Northover      MIB.addOperand(Cond[i]);
40172062f5744557e270a38192554c3126ea5f97434Tim Northover    MIB.addMBB(TBB);
40272062f5744557e270a38192554c3126ea5f97434Tim Northover    return 1;
40372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
40472062f5744557e270a38192554c3126ea5f97434Tim Northover
40572062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
40672062f5744557e270a38192554c3126ea5f97434Tim Northover  for (int i = 1, e = Cond.size(); i != e; ++i)
40772062f5744557e270a38192554c3126ea5f97434Tim Northover    MIB.addOperand(Cond[i]);
40872062f5744557e270a38192554c3126ea5f97434Tim Northover  MIB.addMBB(TBB);
40972062f5744557e270a38192554c3126ea5f97434Tim Northover
41072062f5744557e270a38192554c3126ea5f97434Tim Northover  BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(FBB);
41172062f5744557e270a38192554c3126ea5f97434Tim Northover  return 2;
41272062f5744557e270a38192554c3126ea5f97434Tim Northover}
41372062f5744557e270a38192554c3126ea5f97434Tim Northover
41472062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
41572062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock::iterator I = MBB.end();
41672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin()) return 0;
41772062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
41872062f5744557e270a38192554c3126ea5f97434Tim Northover  while (I->isDebugValue()) {
41972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (I == MBB.begin())
42072062f5744557e270a38192554c3126ea5f97434Tim Northover      return 0;
42172062f5744557e270a38192554c3126ea5f97434Tim Northover    --I;
42272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
42372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I->getOpcode() != AArch64::Bimm && !isCondBranch(I->getOpcode()))
42472062f5744557e270a38192554c3126ea5f97434Tim Northover    return 0;
42572062f5744557e270a38192554c3126ea5f97434Tim Northover
42672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
42772062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
42872062f5744557e270a38192554c3126ea5f97434Tim Northover
42972062f5744557e270a38192554c3126ea5f97434Tim Northover  I = MBB.end();
43072062f5744557e270a38192554c3126ea5f97434Tim Northover
43172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (I == MBB.begin()) return 1;
43272062f5744557e270a38192554c3126ea5f97434Tim Northover  --I;
43372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!isCondBranch(I->getOpcode()))
43472062f5744557e270a38192554c3126ea5f97434Tim Northover    return 1;
43572062f5744557e270a38192554c3126ea5f97434Tim Northover
43672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Remove the branch.
43772062f5744557e270a38192554c3126ea5f97434Tim Northover  I->eraseFromParent();
43872062f5744557e270a38192554c3126ea5f97434Tim Northover  return 2;
43972062f5744557e270a38192554c3126ea5f97434Tim Northover}
44072062f5744557e270a38192554c3126ea5f97434Tim Northover
44172062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
44272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const {
44372062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr &MI = *MBBI;
44472062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock &MBB = *MI.getParent();
44572062f5744557e270a38192554c3126ea5f97434Tim Northover
44672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Opcode = MI.getOpcode();
44772062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Opcode) {
44872062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TLSDESC_BLRx: {
44972062f5744557e270a38192554c3126ea5f97434Tim Northover    MachineInstr *NewMI =
45072062f5744557e270a38192554c3126ea5f97434Tim Northover      BuildMI(MBB, MBBI, MI.getDebugLoc(), get(AArch64::TLSDESCCALL))
45172062f5744557e270a38192554c3126ea5f97434Tim Northover        .addOperand(MI.getOperand(1));
45272062f5744557e270a38192554c3126ea5f97434Tim Northover    MI.setDesc(get(AArch64::BLRx));
45372062f5744557e270a38192554c3126ea5f97434Tim Northover
45472062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm::finalizeBundle(MBB, NewMI, *++MBBI);
45572062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
45672062f5744557e270a38192554c3126ea5f97434Tim Northover    }
45772062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
45872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
45972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
46072062f5744557e270a38192554c3126ea5f97434Tim Northover
46172062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
46272062f5744557e270a38192554c3126ea5f97434Tim Northover}
46372062f5744557e270a38192554c3126ea5f97434Tim Northover
46472062f5744557e270a38192554c3126ea5f97434Tim Northovervoid
46572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
46672062f5744557e270a38192554c3126ea5f97434Tim Northover                                      MachineBasicBlock::iterator MBBI,
46772062f5744557e270a38192554c3126ea5f97434Tim Northover                                      unsigned SrcReg, bool isKill,
46872062f5744557e270a38192554c3126ea5f97434Tim Northover                                      int FrameIdx,
46972062f5744557e270a38192554c3126ea5f97434Tim Northover                                      const TargetRegisterClass *RC,
47072062f5744557e270a38192554c3126ea5f97434Tim Northover                                      const TargetRegisterInfo *TRI) const {
47172062f5744557e270a38192554c3126ea5f97434Tim Northover  DebugLoc DL = MBB.findDebugLoc(MBBI);
47272062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFunction &MF = *MBB.getParent();
47372062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFrameInfo &MFI = *MF.getFrameInfo();
47472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Align = MFI.getObjectAlignment(FrameIdx);
47572062f5744557e270a38192554c3126ea5f97434Tim Northover
47672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineMemOperand *MMO
47772062f5744557e270a38192554c3126ea5f97434Tim Northover    = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
47872062f5744557e270a38192554c3126ea5f97434Tim Northover                              MachineMemOperand::MOStore,
47972062f5744557e270a38192554c3126ea5f97434Tim Northover                              MFI.getObjectSize(FrameIdx),
48072062f5744557e270a38192554c3126ea5f97434Tim Northover                              Align);
48172062f5744557e270a38192554c3126ea5f97434Tim Northover
48272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned StoreOp = 0;
48372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
48472062f5744557e270a38192554c3126ea5f97434Tim Northover    switch(RC->getSize()) {
48572062f5744557e270a38192554c3126ea5f97434Tim Northover    case 4: StoreOp = AArch64::LS32_STR; break;
48672062f5744557e270a38192554c3126ea5f97434Tim Northover    case 8: StoreOp = AArch64::LS64_STR; break;
48772062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
48872062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Unknown size for regclass");
48972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR8RegClass.hasSubClassEq(RC)) {
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StoreOp = AArch64::LSFP8_STR;
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR16RegClass.hasSubClassEq(RC)) {
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StoreOp = AArch64::LSFP16_STR;
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (RC->hasType(MVT::f32) || RC->hasType(MVT::f64) ||
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             RC->hasType(MVT::f128)) {
49672062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (RC->getSize()) {
49772062f5744557e270a38192554c3126ea5f97434Tim Northover    case 4: StoreOp = AArch64::LSFP32_STR; break;
49872062f5744557e270a38192554c3126ea5f97434Tim Northover    case 8: StoreOp = AArch64::LSFP64_STR; break;
49972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 16: StoreOp = AArch64::LSFP128_STR; break;
50072062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
50172062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Unknown size for regclass");
50272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else { // For a super register class has more than one sub registers
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AArch64::DPairRegClass.hasSubClassEq(RC))
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x2_8B;
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::DTripleRegClass.hasSubClassEq(RC))
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x3_8B;
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::DQuadRegClass.hasSubClassEq(RC))
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x4_8B;
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QPairRegClass.hasSubClassEq(RC))
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x2_16B;
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QTripleRegClass.hasSubClassEq(RC))
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x3_16B;
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QQuadRegClass.hasSubClassEq(RC))
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StoreOp = AArch64::ST1x4_16B;
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      llvm_unreachable("Unknown reg class");
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(StoreOp));
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Vector store has different operands from other store instructions.
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI.addFrameIndex(FrameIdx)
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         .addReg(SrcReg, getKillRegState(isKill))
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         .addMemOperand(MMO);
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
52572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
52672062f5744557e270a38192554c3126ea5f97434Tim Northover
52772062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(StoreOp));
52872062f5744557e270a38192554c3126ea5f97434Tim Northover  NewMI.addReg(SrcReg, getKillRegState(isKill))
52972062f5744557e270a38192554c3126ea5f97434Tim Northover    .addFrameIndex(FrameIdx)
53072062f5744557e270a38192554c3126ea5f97434Tim Northover    .addImm(0)
53172062f5744557e270a38192554c3126ea5f97434Tim Northover    .addMemOperand(MMO);
53272062f5744557e270a38192554c3126ea5f97434Tim Northover
53372062f5744557e270a38192554c3126ea5f97434Tim Northover}
53472062f5744557e270a38192554c3126ea5f97434Tim Northover
53572062f5744557e270a38192554c3126ea5f97434Tim Northovervoid
53672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
53772062f5744557e270a38192554c3126ea5f97434Tim Northover                                       MachineBasicBlock::iterator MBBI,
53872062f5744557e270a38192554c3126ea5f97434Tim Northover                                       unsigned DestReg, int FrameIdx,
53972062f5744557e270a38192554c3126ea5f97434Tim Northover                                       const TargetRegisterClass *RC,
54072062f5744557e270a38192554c3126ea5f97434Tim Northover                                       const TargetRegisterInfo *TRI) const {
54172062f5744557e270a38192554c3126ea5f97434Tim Northover  DebugLoc DL = MBB.findDebugLoc(MBBI);
54272062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFunction &MF = *MBB.getParent();
54372062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFrameInfo &MFI = *MF.getFrameInfo();
54472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Align = MFI.getObjectAlignment(FrameIdx);
54572062f5744557e270a38192554c3126ea5f97434Tim Northover
54672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineMemOperand *MMO
54772062f5744557e270a38192554c3126ea5f97434Tim Northover    = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
54872062f5744557e270a38192554c3126ea5f97434Tim Northover                              MachineMemOperand::MOLoad,
54972062f5744557e270a38192554c3126ea5f97434Tim Northover                              MFI.getObjectSize(FrameIdx),
55072062f5744557e270a38192554c3126ea5f97434Tim Northover                              Align);
55172062f5744557e270a38192554c3126ea5f97434Tim Northover
55272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned LoadOp = 0;
55372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
55472062f5744557e270a38192554c3126ea5f97434Tim Northover    switch(RC->getSize()) {
55572062f5744557e270a38192554c3126ea5f97434Tim Northover    case 4: LoadOp = AArch64::LS32_LDR; break;
55672062f5744557e270a38192554c3126ea5f97434Tim Northover    case 8: LoadOp = AArch64::LS64_LDR; break;
55772062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
55872062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Unknown size for regclass");
55972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR8RegClass.hasSubClassEq(RC)) {
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    LoadOp = AArch64::LSFP8_LDR;
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (AArch64::FPR16RegClass.hasSubClassEq(RC)) {
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    LoadOp = AArch64::LSFP16_LDR;
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (RC->hasType(MVT::f32) || RC->hasType(MVT::f64) ||
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             RC->hasType(MVT::f128)) {
56672062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (RC->getSize()) {
56772062f5744557e270a38192554c3126ea5f97434Tim Northover    case 4: LoadOp = AArch64::LSFP32_LDR; break;
56872062f5744557e270a38192554c3126ea5f97434Tim Northover    case 8: LoadOp = AArch64::LSFP64_LDR; break;
56972062f5744557e270a38192554c3126ea5f97434Tim Northover    case 16: LoadOp = AArch64::LSFP128_LDR; break;
57072062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
57172062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Unknown size for regclass");
57272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else { // For a super register class has more than one sub registers
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AArch64::DPairRegClass.hasSubClassEq(RC))
57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x2_8B;
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::DTripleRegClass.hasSubClassEq(RC))
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x3_8B;
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::DQuadRegClass.hasSubClassEq(RC))
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x4_8B;
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QPairRegClass.hasSubClassEq(RC))
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x2_16B;
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QTripleRegClass.hasSubClassEq(RC))
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x3_16B;
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (AArch64::QQuadRegClass.hasSubClassEq(RC))
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LoadOp = AArch64::LD1x4_16B;
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      llvm_unreachable("Unknown reg class");
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(LoadOp), DestReg);
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Vector load has different operands from other load instructions.
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NewMI.addFrameIndex(FrameIdx)
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         .addMemOperand(MMO);
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
59472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
59572062f5744557e270a38192554c3126ea5f97434Tim Northover
59672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(LoadOp), DestReg);
59772062f5744557e270a38192554c3126ea5f97434Tim Northover  NewMI.addFrameIndex(FrameIdx)
59872062f5744557e270a38192554c3126ea5f97434Tim Northover       .addImm(0)
59972062f5744557e270a38192554c3126ea5f97434Tim Northover       .addMemOperand(MMO);
60072062f5744557e270a38192554c3126ea5f97434Tim Northover}
60172062f5744557e270a38192554c3126ea5f97434Tim Northover
60272062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned AArch64InstrInfo::estimateRSStackLimit(MachineFunction &MF) const {
60372062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Limit = (1 << 16) - 1;
60472062f5744557e270a38192554c3126ea5f97434Tim Northover  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
60572062f5744557e270a38192554c3126ea5f97434Tim Northover    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
60672062f5744557e270a38192554c3126ea5f97434Tim Northover         I != E; ++I) {
60772062f5744557e270a38192554c3126ea5f97434Tim Northover      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
60872062f5744557e270a38192554c3126ea5f97434Tim Northover        if (!I->getOperand(i).isFI()) continue;
60972062f5744557e270a38192554c3126ea5f97434Tim Northover
61072062f5744557e270a38192554c3126ea5f97434Tim Northover        // When using ADDxxi_lsl0_s to get the address of a stack object, 0xfff
61172062f5744557e270a38192554c3126ea5f97434Tim Northover        // is the largest offset guaranteed to fit in the immediate offset.
61272062f5744557e270a38192554c3126ea5f97434Tim Northover        if (I->getOpcode() == AArch64::ADDxxi_lsl0_s) {
61372062f5744557e270a38192554c3126ea5f97434Tim Northover          Limit = std::min(Limit, 0xfffu);
61472062f5744557e270a38192554c3126ea5f97434Tim Northover          break;
61572062f5744557e270a38192554c3126ea5f97434Tim Northover        }
61672062f5744557e270a38192554c3126ea5f97434Tim Northover
61772062f5744557e270a38192554c3126ea5f97434Tim Northover        int AccessScale, MinOffset, MaxOffset;
61872062f5744557e270a38192554c3126ea5f97434Tim Northover        getAddressConstraints(*I, AccessScale, MinOffset, MaxOffset);
61972062f5744557e270a38192554c3126ea5f97434Tim Northover        Limit = std::min(Limit, static_cast<unsigned>(MaxOffset));
62072062f5744557e270a38192554c3126ea5f97434Tim Northover
62172062f5744557e270a38192554c3126ea5f97434Tim Northover        break; // At most one FI per instruction
62272062f5744557e270a38192554c3126ea5f97434Tim Northover      }
62372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
62472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
62572062f5744557e270a38192554c3126ea5f97434Tim Northover
62672062f5744557e270a38192554c3126ea5f97434Tim Northover  return Limit;
62772062f5744557e270a38192554c3126ea5f97434Tim Northover}
62872062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64InstrInfo::getAddressConstraints(const MachineInstr &MI,
62972062f5744557e270a38192554c3126ea5f97434Tim Northover                                             int &AccessScale, int &MinOffset,
63072062f5744557e270a38192554c3126ea5f97434Tim Northover                                             int &MaxOffset) const {
63172062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (MI.getOpcode()) {
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Unknown load/store kind");
63472062f5744557e270a38192554c3126ea5f97434Tim Northover  case TargetOpcode::DBG_VALUE:
63572062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 1;
63672062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = INT_MIN;
63772062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = INT_MAX;
63872062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
63972062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LS8_LDR: case AArch64::LS8_STR:
64072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFP8_LDR: case AArch64::LSFP8_STR:
64172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDRSBw:
64272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDRSBx:
64372062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 1;
64472062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
64572062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff;
64672062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
64772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LS16_LDR: case AArch64::LS16_STR:
64872062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFP16_LDR: case AArch64::LSFP16_STR:
64972062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDRSHw:
65072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDRSHx:
65172062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 2;
65272062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
65372062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff * AccessScale;
65472062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
65572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LS32_LDR:  case AArch64::LS32_STR:
65672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFP32_LDR: case AArch64::LSFP32_STR:
65772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDRSWx:
65872062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LDPSWx:
65972062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 4;
66072062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
66172062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff * AccessScale;
66272062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
66372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LS64_LDR: case AArch64::LS64_STR:
66472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFP64_LDR: case AArch64::LSFP64_STR:
66572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::PRFM:
66672062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 8;
66772062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
66872062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff * AccessScale;
66972062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
67072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFP128_LDR: case AArch64::LSFP128_STR:
67172062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 16;
67272062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
67372062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff * AccessScale;
67472062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
67572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSPair32_LDR: case AArch64::LSPair32_STR:
67672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFPPair32_LDR: case AArch64::LSFPPair32_STR:
67772062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 4;
67872062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = -0x40 * AccessScale;
67972062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0x3f * AccessScale;
68072062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
68172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSPair64_LDR: case AArch64::LSPair64_STR:
68272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFPPair64_LDR: case AArch64::LSFPPair64_STR:
68372062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 8;
68472062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = -0x40 * AccessScale;
68572062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0x3f * AccessScale;
68672062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
68772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::LSFPPair128_LDR: case AArch64::LSFPPair128_STR:
68872062f5744557e270a38192554c3126ea5f97434Tim Northover    AccessScale = 16;
68972062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = -0x40 * AccessScale;
69072062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0x3f * AccessScale;
69172062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x2_8B: case AArch64::ST1x2_8B:
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AccessScale = 16;
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MinOffset = 0;
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MaxOffset = 0xfff * AccessScale;
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x3_8B: case AArch64::ST1x3_8B:
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AccessScale = 24;
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MinOffset = 0;
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MaxOffset = 0xfff * AccessScale;
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x4_8B: case AArch64::ST1x4_8B:
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x2_16B: case AArch64::ST1x2_16B:
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AccessScale = 32;
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MinOffset = 0;
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MaxOffset = 0xfff * AccessScale;
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x3_16B: case AArch64::ST1x3_16B:
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AccessScale = 48;
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MinOffset = 0;
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MaxOffset = 0xfff * AccessScale;
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AArch64::LD1x4_16B: case AArch64::ST1x4_16B:
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AccessScale = 64;
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MinOffset = 0;
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MaxOffset = 0xfff * AccessScale;
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
71872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
71972062f5744557e270a38192554c3126ea5f97434Tim Northover}
72072062f5744557e270a38192554c3126ea5f97434Tim Northover
72185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northoverunsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
72285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  const MCInstrDesc &MCID = MI.getDesc();
72385d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  const MachineBasicBlock &MBB = *MI.getParent();
72485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  const MachineFunction &MF = *MBB.getParent();
72585d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  const MCAsmInfo &MAI = *MF.getTarget().getMCAsmInfo();
72685d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
72785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  if (MCID.getSize())
72885d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    return MCID.getSize();
72985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
73085d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  if (MI.getOpcode() == AArch64::INLINEASM)
73185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    return getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI);
73285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
73385d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  switch (MI.getOpcode()) {
73485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case TargetOpcode::BUNDLE:
73585d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    return getInstBundleLength(MI);
73685d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case TargetOpcode::IMPLICIT_DEF:
73785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case TargetOpcode::KILL:
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case TargetOpcode::CFI_INSTRUCTION:
73985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case TargetOpcode::EH_LABEL:
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case TargetOpcode::GC_LABEL:
74185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case TargetOpcode::DBG_VALUE:
74285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  case AArch64::TLSDESCCALL:
74385d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    return 0;
74485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  default:
74585d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    llvm_unreachable("Unknown instruction class");
74685d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
74785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
74885d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
74985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northoverunsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const {
75085d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  unsigned Size = 0;
75185d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  MachineBasicBlock::const_instr_iterator I = MI;
75285d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
75385d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  while (++I != E && I->isInsideBundle()) {
75485d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    assert(!I->isBundle() && "No nested bundle!");
75585d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover    Size += getInstSizeInBytes(*I);
75685d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  }
75785d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover  return Size;
75885d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover}
75985d2760c8e1d36657ae4d86a6aeee03b3a723d9cTim Northover
76072062f5744557e270a38192554c3126ea5f97434Tim Northoverbool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
76172062f5744557e270a38192554c3126ea5f97434Tim Northover                                unsigned FrameReg, int &Offset,
76272062f5744557e270a38192554c3126ea5f97434Tim Northover                                const AArch64InstrInfo &TII) {
76372062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock &MBB = *MI.getParent();
76472062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFunction &MF = *MBB.getParent();
76572062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFrameInfo &MFI = *MF.getFrameInfo();
76672062f5744557e270a38192554c3126ea5f97434Tim Northover
76772062f5744557e270a38192554c3126ea5f97434Tim Northover  MFI.getObjectOffset(FrameRegIdx);
76872062f5744557e270a38192554c3126ea5f97434Tim Northover  llvm_unreachable("Unimplemented rewriteFrameIndex");
76972062f5744557e270a38192554c3126ea5f97434Tim Northover}
77072062f5744557e270a38192554c3126ea5f97434Tim Northover
771dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northovervoid llvm::emitRegUpdate(MachineBasicBlock &MBB,
772dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                         MachineBasicBlock::iterator MBBI,
77372062f5744557e270a38192554c3126ea5f97434Tim Northover                         DebugLoc dl, const TargetInstrInfo &TII,
77472062f5744557e270a38192554c3126ea5f97434Tim Northover                         unsigned DstReg, unsigned SrcReg, unsigned ScratchReg,
77572062f5744557e270a38192554c3126ea5f97434Tim Northover                         int64_t NumBytes, MachineInstr::MIFlag MIFlags) {
77672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (NumBytes == 0 && DstReg == SrcReg)
77772062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
778fe37e6279ebbb4ba1eede4bcb8dfe732f0bbcb38Tim Northover  else if (abs64(NumBytes) & ~0xffffff) {
77972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Generically, we have to materialize the offset into a temporary register
78072062f5744557e270a38192554c3126ea5f97434Tim Northover    // and subtract it. There are a couple of ways this could be done, for now
781148ac534fc5592ed7031efde9a577890f078068bTim Northover    // we'll use a movz/movk or movn/movk sequence.
782fe37e6279ebbb4ba1eede4bcb8dfe732f0bbcb38Tim Northover    uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes));
783148ac534fc5592ed7031efde9a577890f078068bTim Northover    BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
784148ac534fc5592ed7031efde9a577890f078068bTim Northover      .addImm(0xffff & Bits).addImm(0)
785148ac534fc5592ed7031efde9a577890f078068bTim Northover      .setMIFlags(MIFlags);
786148ac534fc5592ed7031efde9a577890f078068bTim Northover
787148ac534fc5592ed7031efde9a577890f078068bTim Northover    Bits >>= 16;
788148ac534fc5592ed7031efde9a577890f078068bTim Northover    if (Bits & 0xffff) {
789148ac534fc5592ed7031efde9a577890f078068bTim Northover      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
790148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addReg(ScratchReg)
791148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addImm(0xffff & Bits).addImm(1)
792148ac534fc5592ed7031efde9a577890f078068bTim Northover        .setMIFlags(MIFlags);
793148ac534fc5592ed7031efde9a577890f078068bTim Northover    }
794148ac534fc5592ed7031efde9a577890f078068bTim Northover
795148ac534fc5592ed7031efde9a577890f078068bTim Northover    Bits >>= 16;
796148ac534fc5592ed7031efde9a577890f078068bTim Northover    if (Bits & 0xffff) {
797148ac534fc5592ed7031efde9a577890f078068bTim Northover      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
798148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addReg(ScratchReg)
799148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addImm(0xffff & Bits).addImm(2)
800148ac534fc5592ed7031efde9a577890f078068bTim Northover        .setMIFlags(MIFlags);
801148ac534fc5592ed7031efde9a577890f078068bTim Northover    }
802148ac534fc5592ed7031efde9a577890f078068bTim Northover
803148ac534fc5592ed7031efde9a577890f078068bTim Northover    Bits >>= 16;
804148ac534fc5592ed7031efde9a577890f078068bTim Northover    if (Bits & 0xffff) {
805148ac534fc5592ed7031efde9a577890f078068bTim Northover      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
806148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addReg(ScratchReg)
807148ac534fc5592ed7031efde9a577890f078068bTim Northover        .addImm(0xffff & Bits).addImm(3)
808148ac534fc5592ed7031efde9a577890f078068bTim Northover        .setMIFlags(MIFlags);
809148ac534fc5592ed7031efde9a577890f078068bTim Northover    }
81072062f5744557e270a38192554c3126ea5f97434Tim Northover
81172062f5744557e270a38192554c3126ea5f97434Tim Northover    // ADD DST, SRC, xTMP (, lsl #0)
81272062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
81372062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, MBBI, dl, TII.get(AddOp), DstReg)
81472062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg, RegState::Kill)
81572062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(ScratchReg, RegState::Kill)
81672062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(0)
81772062f5744557e270a38192554c3126ea5f97434Tim Northover      .setMIFlag(MIFlags);
81872062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
81972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
82072062f5744557e270a38192554c3126ea5f97434Tim Northover
82172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Now we know that the adjustment can be done in at most two add/sub
82272062f5744557e270a38192554c3126ea5f97434Tim Northover  // (immediate) instructions, which is always more efficient than a
82372062f5744557e270a38192554c3126ea5f97434Tim Northover  // literal-pool load, or even a hypothetical movz/movk/add sequence
82472062f5744557e270a38192554c3126ea5f97434Tim Northover
82572062f5744557e270a38192554c3126ea5f97434Tim Northover  // Decide whether we're doing addition or subtraction
82672062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned LowOp, HighOp;
82772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (NumBytes >= 0) {
82872062f5744557e270a38192554c3126ea5f97434Tim Northover    LowOp = AArch64::ADDxxi_lsl0_s;
82972062f5744557e270a38192554c3126ea5f97434Tim Northover    HighOp = AArch64::ADDxxi_lsl12_s;
83072062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
83172062f5744557e270a38192554c3126ea5f97434Tim Northover    LowOp = AArch64::SUBxxi_lsl0_s;
83272062f5744557e270a38192554c3126ea5f97434Tim Northover    HighOp = AArch64::SUBxxi_lsl12_s;
833fe37e6279ebbb4ba1eede4bcb8dfe732f0bbcb38Tim Northover    NumBytes = abs64(NumBytes);
83472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
83572062f5744557e270a38192554c3126ea5f97434Tim Northover
83672062f5744557e270a38192554c3126ea5f97434Tim Northover  // If we're here, at the very least a move needs to be produced, which just
83772062f5744557e270a38192554c3126ea5f97434Tim Northover  // happens to be materializable by an ADD.
83872062f5744557e270a38192554c3126ea5f97434Tim Northover  if ((NumBytes & 0xfff) || NumBytes == 0) {
83972062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, MBBI, dl, TII.get(LowOp), DstReg)
84072062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg, RegState::Kill)
84172062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(NumBytes & 0xfff)
84272062f5744557e270a38192554c3126ea5f97434Tim Northover      .setMIFlag(MIFlags);
84372062f5744557e270a38192554c3126ea5f97434Tim Northover
84472062f5744557e270a38192554c3126ea5f97434Tim Northover    // Next update should use the register we've just defined.
84572062f5744557e270a38192554c3126ea5f97434Tim Northover    SrcReg = DstReg;
84672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
84772062f5744557e270a38192554c3126ea5f97434Tim Northover
84872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (NumBytes & 0xfff000) {
84972062f5744557e270a38192554c3126ea5f97434Tim Northover    BuildMI(MBB, MBBI, dl, TII.get(HighOp), DstReg)
85072062f5744557e270a38192554c3126ea5f97434Tim Northover      .addReg(SrcReg, RegState::Kill)
85172062f5744557e270a38192554c3126ea5f97434Tim Northover      .addImm(NumBytes >> 12)
85272062f5744557e270a38192554c3126ea5f97434Tim Northover      .setMIFlag(MIFlags);
85372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
85472062f5744557e270a38192554c3126ea5f97434Tim Northover}
85572062f5744557e270a38192554c3126ea5f97434Tim Northover
85672062f5744557e270a38192554c3126ea5f97434Tim Northovervoid llvm::emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
85772062f5744557e270a38192554c3126ea5f97434Tim Northover                        DebugLoc dl, const TargetInstrInfo &TII,
85872062f5744557e270a38192554c3126ea5f97434Tim Northover                        unsigned ScratchReg, int64_t NumBytes,
85972062f5744557e270a38192554c3126ea5f97434Tim Northover                        MachineInstr::MIFlag MIFlags) {
86072062f5744557e270a38192554c3126ea5f97434Tim Northover  emitRegUpdate(MBB, MI, dl, TII, AArch64::XSP, AArch64::XSP, AArch64::X16,
86172062f5744557e270a38192554c3126ea5f97434Tim Northover                NumBytes, MIFlags);
86272062f5744557e270a38192554c3126ea5f97434Tim Northover}
86372062f5744557e270a38192554c3126ea5f97434Tim Northover
86472062f5744557e270a38192554c3126ea5f97434Tim Northover
86572062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
86672062f5744557e270a38192554c3126ea5f97434Tim Northover  struct LDTLSCleanup : public MachineFunctionPass {
86772062f5744557e270a38192554c3126ea5f97434Tim Northover    static char ID;
86872062f5744557e270a38192554c3126ea5f97434Tim Northover    LDTLSCleanup() : MachineFunctionPass(ID) {}
86972062f5744557e270a38192554c3126ea5f97434Tim Northover
87072062f5744557e270a38192554c3126ea5f97434Tim Northover    virtual bool runOnMachineFunction(MachineFunction &MF) {
871dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover      AArch64MachineFunctionInfo* MFI
872dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover        = MF.getInfo<AArch64MachineFunctionInfo>();
87372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
87472062f5744557e270a38192554c3126ea5f97434Tim Northover        // No point folding accesses if there isn't at least two.
87572062f5744557e270a38192554c3126ea5f97434Tim Northover        return false;
87672062f5744557e270a38192554c3126ea5f97434Tim Northover      }
87772062f5744557e270a38192554c3126ea5f97434Tim Northover
87872062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
87972062f5744557e270a38192554c3126ea5f97434Tim Northover      return VisitNode(DT->getRootNode(), 0);
88072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
88172062f5744557e270a38192554c3126ea5f97434Tim Northover
88272062f5744557e270a38192554c3126ea5f97434Tim Northover    // Visit the dominator subtree rooted at Node in pre-order.
88372062f5744557e270a38192554c3126ea5f97434Tim Northover    // If TLSBaseAddrReg is non-null, then use that to replace any
88472062f5744557e270a38192554c3126ea5f97434Tim Northover    // TLS_base_addr instructions. Otherwise, create the register
88572062f5744557e270a38192554c3126ea5f97434Tim Northover    // when the first such instruction is seen, and then use it
88672062f5744557e270a38192554c3126ea5f97434Tim Northover    // as we encounter more instructions.
88772062f5744557e270a38192554c3126ea5f97434Tim Northover    bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
88872062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineBasicBlock *BB = Node->getBlock();
88972062f5744557e270a38192554c3126ea5f97434Tim Northover      bool Changed = false;
89072062f5744557e270a38192554c3126ea5f97434Tim Northover
89172062f5744557e270a38192554c3126ea5f97434Tim Northover      // Traverse the current block.
89272062f5744557e270a38192554c3126ea5f97434Tim Northover      for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
89372062f5744557e270a38192554c3126ea5f97434Tim Northover           ++I) {
89472062f5744557e270a38192554c3126ea5f97434Tim Northover        switch (I->getOpcode()) {
89572062f5744557e270a38192554c3126ea5f97434Tim Northover        case AArch64::TLSDESC_BLRx:
89672062f5744557e270a38192554c3126ea5f97434Tim Northover          // Make sure it's a local dynamic access.
89772062f5744557e270a38192554c3126ea5f97434Tim Northover          if (!I->getOperand(1).isSymbol() ||
89872062f5744557e270a38192554c3126ea5f97434Tim Northover              strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
89972062f5744557e270a38192554c3126ea5f97434Tim Northover            break;
90072062f5744557e270a38192554c3126ea5f97434Tim Northover
90172062f5744557e270a38192554c3126ea5f97434Tim Northover          if (TLSBaseAddrReg)
90272062f5744557e270a38192554c3126ea5f97434Tim Northover            I = ReplaceTLSBaseAddrCall(I, TLSBaseAddrReg);
90372062f5744557e270a38192554c3126ea5f97434Tim Northover          else
90472062f5744557e270a38192554c3126ea5f97434Tim Northover            I = SetRegister(I, &TLSBaseAddrReg);
90572062f5744557e270a38192554c3126ea5f97434Tim Northover          Changed = true;
90672062f5744557e270a38192554c3126ea5f97434Tim Northover          break;
90772062f5744557e270a38192554c3126ea5f97434Tim Northover        default:
90872062f5744557e270a38192554c3126ea5f97434Tim Northover          break;
90972062f5744557e270a38192554c3126ea5f97434Tim Northover        }
91072062f5744557e270a38192554c3126ea5f97434Tim Northover      }
91172062f5744557e270a38192554c3126ea5f97434Tim Northover
91272062f5744557e270a38192554c3126ea5f97434Tim Northover      // Visit the children of this block in the dominator tree.
91372062f5744557e270a38192554c3126ea5f97434Tim Northover      for (MachineDomTreeNode::iterator I = Node->begin(), E = Node->end();
91472062f5744557e270a38192554c3126ea5f97434Tim Northover           I != E; ++I) {
91572062f5744557e270a38192554c3126ea5f97434Tim Northover        Changed |= VisitNode(*I, TLSBaseAddrReg);
91672062f5744557e270a38192554c3126ea5f97434Tim Northover      }
91772062f5744557e270a38192554c3126ea5f97434Tim Northover
91872062f5744557e270a38192554c3126ea5f97434Tim Northover      return Changed;
91972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
92072062f5744557e270a38192554c3126ea5f97434Tim Northover
92172062f5744557e270a38192554c3126ea5f97434Tim Northover    // Replace the TLS_base_addr instruction I with a copy from
92272062f5744557e270a38192554c3126ea5f97434Tim Northover    // TLSBaseAddrReg, returning the new instruction.
92372062f5744557e270a38192554c3126ea5f97434Tim Northover    MachineInstr *ReplaceTLSBaseAddrCall(MachineInstr *I,
92472062f5744557e270a38192554c3126ea5f97434Tim Northover                                         unsigned TLSBaseAddrReg) {
92572062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineFunction *MF = I->getParent()->getParent();
92672062f5744557e270a38192554c3126ea5f97434Tim Northover      const AArch64TargetMachine *TM =
92772062f5744557e270a38192554c3126ea5f97434Tim Northover          static_cast<const AArch64TargetMachine *>(&MF->getTarget());
92872062f5744557e270a38192554c3126ea5f97434Tim Northover      const AArch64InstrInfo *TII = TM->getInstrInfo();
92972062f5744557e270a38192554c3126ea5f97434Tim Northover
93072062f5744557e270a38192554c3126ea5f97434Tim Northover      // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
93172062f5744557e270a38192554c3126ea5f97434Tim Northover      // code sequence assumes the address will be.
93272062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
93372062f5744557e270a38192554c3126ea5f97434Tim Northover                                   TII->get(TargetOpcode::COPY),
93472062f5744557e270a38192554c3126ea5f97434Tim Northover                                   AArch64::X0)
93572062f5744557e270a38192554c3126ea5f97434Tim Northover        .addReg(TLSBaseAddrReg);
93672062f5744557e270a38192554c3126ea5f97434Tim Northover
93772062f5744557e270a38192554c3126ea5f97434Tim Northover      // Erase the TLS_base_addr instruction.
93872062f5744557e270a38192554c3126ea5f97434Tim Northover      I->eraseFromParent();
93972062f5744557e270a38192554c3126ea5f97434Tim Northover
94072062f5744557e270a38192554c3126ea5f97434Tim Northover      return Copy;
94172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
94272062f5744557e270a38192554c3126ea5f97434Tim Northover
94372062f5744557e270a38192554c3126ea5f97434Tim Northover    // Create a virtal register in *TLSBaseAddrReg, and populate it by
94472062f5744557e270a38192554c3126ea5f97434Tim Northover    // inserting a copy instruction after I. Returns the new instruction.
94572062f5744557e270a38192554c3126ea5f97434Tim Northover    MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) {
94672062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineFunction *MF = I->getParent()->getParent();
94772062f5744557e270a38192554c3126ea5f97434Tim Northover      const AArch64TargetMachine *TM =
94872062f5744557e270a38192554c3126ea5f97434Tim Northover          static_cast<const AArch64TargetMachine *>(&MF->getTarget());
94972062f5744557e270a38192554c3126ea5f97434Tim Northover      const AArch64InstrInfo *TII = TM->getInstrInfo();
95072062f5744557e270a38192554c3126ea5f97434Tim Northover
95172062f5744557e270a38192554c3126ea5f97434Tim Northover      // Create a virtual register for the TLS base address.
95272062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineRegisterInfo &RegInfo = MF->getRegInfo();
95372062f5744557e270a38192554c3126ea5f97434Tim Northover      *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
95472062f5744557e270a38192554c3126ea5f97434Tim Northover
95572062f5744557e270a38192554c3126ea5f97434Tim Northover      // Insert a copy from X0 to TLSBaseAddrReg for later.
95672062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineInstr *Next = I->getNextNode();
95772062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
95872062f5744557e270a38192554c3126ea5f97434Tim Northover                                   TII->get(TargetOpcode::COPY),
95972062f5744557e270a38192554c3126ea5f97434Tim Northover                                   *TLSBaseAddrReg)
96072062f5744557e270a38192554c3126ea5f97434Tim Northover        .addReg(AArch64::X0);
96172062f5744557e270a38192554c3126ea5f97434Tim Northover
96272062f5744557e270a38192554c3126ea5f97434Tim Northover      return Copy;
96372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
96472062f5744557e270a38192554c3126ea5f97434Tim Northover
96572062f5744557e270a38192554c3126ea5f97434Tim Northover    virtual const char *getPassName() const {
96672062f5744557e270a38192554c3126ea5f97434Tim Northover      return "Local Dynamic TLS Access Clean-up";
96772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
96872062f5744557e270a38192554c3126ea5f97434Tim Northover
96972062f5744557e270a38192554c3126ea5f97434Tim Northover    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
97072062f5744557e270a38192554c3126ea5f97434Tim Northover      AU.setPreservesCFG();
97172062f5744557e270a38192554c3126ea5f97434Tim Northover      AU.addRequired<MachineDominatorTree>();
97272062f5744557e270a38192554c3126ea5f97434Tim Northover      MachineFunctionPass::getAnalysisUsage(AU);
97372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
97472062f5744557e270a38192554c3126ea5f97434Tim Northover  };
97572062f5744557e270a38192554c3126ea5f97434Tim Northover}
97672062f5744557e270a38192554c3126ea5f97434Tim Northover
97772062f5744557e270a38192554c3126ea5f97434Tim Northoverchar LDTLSCleanup::ID = 0;
97872062f5744557e270a38192554c3126ea5f97434Tim NorthoverFunctionPass*
97972062f5744557e270a38192554c3126ea5f97434Tim Northoverllvm::createAArch64CleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); }
980