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