172062f5744557e270a38192554c3126ea5f97434Tim Northover//===- AArch64RegisterInfo.cpp - AArch64 Register 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//
10dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover// This file contains the AArch64 implementation of the TargetRegisterInfo
11dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover// class.
1272062f5744557e270a38192554c3126ea5f97434Tim Northover//
1372062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
1472062f5744557e270a38192554c3126ea5f97434Tim Northover
1572062f5744557e270a38192554c3126ea5f97434Tim Northover
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64RegisterInfo.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64FrameLowering.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MachineFunctionInfo.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64TargetMachine.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCTargetDesc.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFrameInfo.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineInstrBuilder.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineRegisterInfo.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/RegisterScavenging.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/BitVector.h"
2672062f5744557e270a38192554c3126ea5f97434Tim Northover
2772062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_REGINFO_TARGET_DESC
2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenRegisterInfo.inc"
2972062f5744557e270a38192554c3126ea5f97434Tim Northover
3072062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3172062f5744557e270a38192554c3126ea5f97434Tim Northover
3272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo &tii,
3372062f5744557e270a38192554c3126ea5f97434Tim Northover                                         const AArch64Subtarget &sti)
3472062f5744557e270a38192554c3126ea5f97434Tim Northover  : AArch64GenRegisterInfo(AArch64::X30), TII(tii) {
3572062f5744557e270a38192554c3126ea5f97434Tim Northover}
3672062f5744557e270a38192554c3126ea5f97434Tim Northover
3772062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint16_t *
3872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
3972062f5744557e270a38192554c3126ea5f97434Tim Northover  return CSR_PCS_SaveList;
4072062f5744557e270a38192554c3126ea5f97434Tim Northover}
4172062f5744557e270a38192554c3126ea5f97434Tim Northover
4272062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint32_t*
4372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const {
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  return CSR_PCS_RegMask;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover}
4672062f5744557e270a38192554c3126ea5f97434Tim Northover
4772062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const {
4872062f5744557e270a38192554c3126ea5f97434Tim Northover  return TLSDesc_RegMask;
4972062f5744557e270a38192554c3126ea5f97434Tim Northover}
5072062f5744557e270a38192554c3126ea5f97434Tim Northover
5172062f5744557e270a38192554c3126ea5f97434Tim Northoverconst TargetRegisterClass *
5272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
5372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RC == &AArch64::FlagClassRegClass)
5472062f5744557e270a38192554c3126ea5f97434Tim Northover    return &AArch64::GPR64RegClass;
5572062f5744557e270a38192554c3126ea5f97434Tim Northover
5672062f5744557e270a38192554c3126ea5f97434Tim Northover  return RC;
5772062f5744557e270a38192554c3126ea5f97434Tim Northover}
5872062f5744557e270a38192554c3126ea5f97434Tim Northover
5972062f5744557e270a38192554c3126ea5f97434Tim Northover
6072062f5744557e270a38192554c3126ea5f97434Tim Northover
6172062f5744557e270a38192554c3126ea5f97434Tim NorthoverBitVector
6272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
6372062f5744557e270a38192554c3126ea5f97434Tim Northover  BitVector Reserved(getNumRegs());
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
6572062f5744557e270a38192554c3126ea5f97434Tim Northover
6672062f5744557e270a38192554c3126ea5f97434Tim Northover  Reserved.set(AArch64::XSP);
6772062f5744557e270a38192554c3126ea5f97434Tim Northover  Reserved.set(AArch64::WSP);
6872062f5744557e270a38192554c3126ea5f97434Tim Northover
6972062f5744557e270a38192554c3126ea5f97434Tim Northover  Reserved.set(AArch64::XZR);
7072062f5744557e270a38192554c3126ea5f97434Tim Northover  Reserved.set(AArch64::WZR);
7172062f5744557e270a38192554c3126ea5f97434Tim Northover
7272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (TFI->hasFP(MF)) {
7372062f5744557e270a38192554c3126ea5f97434Tim Northover    Reserved.set(AArch64::X29);
7472062f5744557e270a38192554c3126ea5f97434Tim Northover    Reserved.set(AArch64::W29);
7572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
7672062f5744557e270a38192554c3126ea5f97434Tim Northover
7772062f5744557e270a38192554c3126ea5f97434Tim Northover  return Reserved;
7872062f5744557e270a38192554c3126ea5f97434Tim Northover}
7972062f5744557e270a38192554c3126ea5f97434Tim Northover
8072062f5744557e270a38192554c3126ea5f97434Tim Northovervoid
8172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI,
82a9da5c50e246966c04784756e2083dbfe606c448Tim Northover                                         int SPAdj,
83a9da5c50e246966c04784756e2083dbfe606c448Tim Northover                                         unsigned FIOperandNum,
84a9da5c50e246966c04784756e2083dbfe606c448Tim Northover                                         RegScavenger *RS) const {
8572062f5744557e270a38192554c3126ea5f97434Tim Northover  assert(SPAdj == 0 && "Cannot deal with nonzero SPAdj yet");
8672062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineInstr &MI = *MBBI;
8772062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineBasicBlock &MBB = *MI.getParent();
8872062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFunction &MF = *MBB.getParent();
8972062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineFrameInfo *MFI = MF.getFrameInfo();
9072062f5744557e270a38192554c3126ea5f97434Tim Northover  const AArch64FrameLowering *TFI =
91dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover   static_cast<const AArch64FrameLowering *>(MF.getTarget().getFrameLowering());
9272062f5744557e270a38192554c3126ea5f97434Tim Northover
9372062f5744557e270a38192554c3126ea5f97434Tim Northover  // In order to work out the base and offset for addressing, the FrameLowering
9472062f5744557e270a38192554c3126ea5f97434Tim Northover  // code needs to know (sometimes) whether the instruction is storing/loading a
9572062f5744557e270a38192554c3126ea5f97434Tim Northover  // callee-saved register, or whether it's a more generic
9672062f5744557e270a38192554c3126ea5f97434Tim Northover  // operation. Fortunately the frame indices are used *only* for that purpose
9772062f5744557e270a38192554c3126ea5f97434Tim Northover  // and are contiguous, so we can check here.
9872062f5744557e270a38192554c3126ea5f97434Tim Northover  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
9972062f5744557e270a38192554c3126ea5f97434Tim Northover  int MinCSFI = 0;
10072062f5744557e270a38192554c3126ea5f97434Tim Northover  int MaxCSFI = -1;
10172062f5744557e270a38192554c3126ea5f97434Tim Northover
10272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (CSI.size()) {
10372062f5744557e270a38192554c3126ea5f97434Tim Northover    MinCSFI = CSI[0].getFrameIdx();
10472062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
10572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
10672062f5744557e270a38192554c3126ea5f97434Tim Northover
107a9da5c50e246966c04784756e2083dbfe606c448Tim Northover  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
10872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI;
10972062f5744557e270a38192554c3126ea5f97434Tim Northover
11072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned FrameReg;
11172062f5744557e270a38192554c3126ea5f97434Tim Northover  int64_t Offset;
11272062f5744557e270a38192554c3126ea5f97434Tim Northover  Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj,
11372062f5744557e270a38192554c3126ea5f97434Tim Northover                                           IsCalleeSaveOp);
11472062f5744557e270a38192554c3126ea5f97434Tim Northover
115a9da5c50e246966c04784756e2083dbfe606c448Tim Northover  Offset += MI.getOperand(FIOperandNum + 1).getImm();
11672062f5744557e270a38192554c3126ea5f97434Tim Northover
11772062f5744557e270a38192554c3126ea5f97434Tim Northover  // DBG_VALUE instructions have no real restrictions so they can be handled
11872062f5744557e270a38192554c3126ea5f97434Tim Northover  // easily.
11972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (MI.isDebugValue()) {
120a9da5c50e246966c04784756e2083dbfe606c448Tim Northover    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/ false);
121a9da5c50e246966c04784756e2083dbfe606c448Tim Northover    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
12272062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
12372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12472062f5744557e270a38192554c3126ea5f97434Tim Northover
12572062f5744557e270a38192554c3126ea5f97434Tim Northover  int MinOffset, MaxOffset, OffsetScale;
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) {
12772062f5744557e270a38192554c3126ea5f97434Tim Northover    MinOffset = 0;
12872062f5744557e270a38192554c3126ea5f97434Tim Northover    MaxOffset = 0xfff;
12972062f5744557e270a38192554c3126ea5f97434Tim Northover    OffsetScale = 1;
13072062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
13172062f5744557e270a38192554c3126ea5f97434Tim Northover    // Load/store of a stack object
13272062f5744557e270a38192554c3126ea5f97434Tim Northover    TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset);
13372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
13472062f5744557e270a38192554c3126ea5f97434Tim Northover
13572062f5744557e270a38192554c3126ea5f97434Tim Northover  // The frame lowering has told us a base and offset it thinks we should use to
13672062f5744557e270a38192554c3126ea5f97434Tim Northover  // access this variable, but it's still up to us to make sure the values are
13772062f5744557e270a38192554c3126ea5f97434Tim Northover  // legal for the instruction in question.
13872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) {
13972062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned BaseReg =
14072062f5744557e270a38192554c3126ea5f97434Tim Northover      MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
14172062f5744557e270a38192554c3126ea5f97434Tim Northover    emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII,
14272062f5744557e270a38192554c3126ea5f97434Tim Northover                  BaseReg, FrameReg, BaseReg, Offset);
14372062f5744557e270a38192554c3126ea5f97434Tim Northover    FrameReg = BaseReg;
14472062f5744557e270a38192554c3126ea5f97434Tim Northover    Offset = 0;
14572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14672062f5744557e270a38192554c3126ea5f97434Tim Northover
14772062f5744557e270a38192554c3126ea5f97434Tim Northover  // Negative offsets are expected if we address from FP, but for
14872062f5744557e270a38192554c3126ea5f97434Tim Northover  // now this checks nothing has gone horribly wrong.
14972062f5744557e270a38192554c3126ea5f97434Tim Northover  assert(Offset >= 0 && "Unexpected negative offset from SP");
15072062f5744557e270a38192554c3126ea5f97434Tim Northover
151a9da5c50e246966c04784756e2083dbfe606c448Tim Northover  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, true);
152a9da5c50e246966c04784756e2083dbfe606c448Tim Northover  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale);
15372062f5744557e270a38192554c3126ea5f97434Tim Northover}
15472062f5744557e270a38192554c3126ea5f97434Tim Northover
15572062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned
15672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
15772062f5744557e270a38192554c3126ea5f97434Tim Northover  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
15872062f5744557e270a38192554c3126ea5f97434Tim Northover
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (TFI->hasFP(MF))
16072062f5744557e270a38192554c3126ea5f97434Tim Northover    return AArch64::X29;
16172062f5744557e270a38192554c3126ea5f97434Tim Northover  else
16272062f5744557e270a38192554c3126ea5f97434Tim Northover    return AArch64::XSP;
16372062f5744557e270a38192554c3126ea5f97434Tim Northover}
16472062f5744557e270a38192554c3126ea5f97434Tim Northover
16572062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
16672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
16772062f5744557e270a38192554c3126ea5f97434Tim Northover  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
168dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  const AArch64FrameLowering *AFI
169dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover    = static_cast<const AArch64FrameLowering*>(TFI);
17072062f5744557e270a38192554c3126ea5f97434Tim Northover  return AFI->useFPForAddressing(MF);
17172062f5744557e270a38192554c3126ea5f97434Tim Northover}
172