1//===-- SIRegisterInfo.cpp - SI Register Information ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// \brief SI implementation of the TargetRegisterInfo class.
12//
13//===----------------------------------------------------------------------===//
14
15
16#include "SIRegisterInfo.h"
17#include "AMDGPUSubtarget.h"
18#include "SIInstrInfo.h"
19
20using namespace llvm;
21
22SIRegisterInfo::SIRegisterInfo(const AMDGPUSubtarget &st)
23: AMDGPURegisterInfo(st)
24  { }
25
26BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
27  BitVector Reserved(getNumRegs());
28  Reserved.set(AMDGPU::EXEC);
29  Reserved.set(AMDGPU::INDIRECT_BASE_ADDR);
30  const SIInstrInfo *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());
31  TII->reserveIndirectRegisters(Reserved, MF);
32  return Reserved;
33}
34
35unsigned SIRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
36                                             MachineFunction &MF) const {
37  return RC->getNumRegs();
38}
39
40const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
41                                                                   MVT VT) const {
42  switch(VT.SimpleTy) {
43    default:
44    case MVT::i32: return &AMDGPU::VReg_32RegClass;
45  }
46}
47
48unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const {
49  return getEncodingValue(Reg) & 0xff;
50}
51
52const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const {
53  assert(!TargetRegisterInfo::isVirtualRegister(Reg));
54
55  const TargetRegisterClass *BaseClasses[] = {
56    &AMDGPU::VReg_32RegClass,
57    &AMDGPU::SReg_32RegClass,
58    &AMDGPU::VReg_64RegClass,
59    &AMDGPU::SReg_64RegClass,
60    &AMDGPU::SReg_128RegClass,
61    &AMDGPU::SReg_256RegClass
62  };
63
64  for (const TargetRegisterClass *BaseClass : BaseClasses) {
65    if (BaseClass->contains(Reg)) {
66      return BaseClass;
67    }
68  }
69  return nullptr;
70}
71
72bool SIRegisterInfo::isSGPRClass(const TargetRegisterClass *RC) const {
73  if (!RC) {
74    return false;
75  }
76  return !hasVGPRs(RC);
77}
78
79bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const {
80  return getCommonSubClass(&AMDGPU::VReg_32RegClass, RC) ||
81         getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) ||
82         getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) ||
83         getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) ||
84         getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) ||
85         getCommonSubClass(&AMDGPU::VReg_512RegClass, RC);
86}
87
88const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass(
89                                         const TargetRegisterClass *SRC) const {
90    if (hasVGPRs(SRC)) {
91      return SRC;
92    } else if (SRC == &AMDGPU::SCCRegRegClass) {
93      return &AMDGPU::VCCRegRegClass;
94    } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_32RegClass)) {
95      return &AMDGPU::VReg_32RegClass;
96    } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_64RegClass)) {
97      return &AMDGPU::VReg_64RegClass;
98    } else if (getCommonSubClass(SRC, &AMDGPU::SReg_128RegClass)) {
99      return &AMDGPU::VReg_128RegClass;
100    } else if (getCommonSubClass(SRC, &AMDGPU::SReg_256RegClass)) {
101      return &AMDGPU::VReg_256RegClass;
102    } else if (getCommonSubClass(SRC, &AMDGPU::SReg_512RegClass)) {
103      return &AMDGPU::VReg_512RegClass;
104    }
105    return nullptr;
106}
107
108const TargetRegisterClass *SIRegisterInfo::getSubRegClass(
109                         const TargetRegisterClass *RC, unsigned SubIdx) const {
110  if (SubIdx == AMDGPU::NoSubRegister)
111    return RC;
112
113  // If this register has a sub-register, we can safely assume it is a 32-bit
114  // register, because all of SI's sub-registers are 32-bit.
115  if (isSGPRClass(RC)) {
116    return &AMDGPU::SGPR_32RegClass;
117  } else {
118    return &AMDGPU::VGPR_32RegClass;
119  }
120}
121
122unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
123                                          const TargetRegisterClass *SubRC,
124                                          unsigned Channel) const {
125  unsigned Index = getHWRegIndex(Reg);
126  return SubRC->getRegister(Index + Channel);
127}
128
129bool SIRegisterInfo::regClassCanUseImmediate(int RCID) const {
130  switch (RCID) {
131  default: return false;
132  case AMDGPU::SSrc_32RegClassID:
133  case AMDGPU::SSrc_64RegClassID:
134  case AMDGPU::VSrc_32RegClassID:
135  case AMDGPU::VSrc_64RegClassID:
136    return true;
137  }
138}
139
140bool SIRegisterInfo::regClassCanUseImmediate(
141                             const TargetRegisterClass *RC) const {
142  return regClassCanUseImmediate(RC->getID());
143}
144