1//===-- HexagonRegisterInfo.cpp - Hexagon 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// This file contains the Hexagon implementation of the TargetRegisterInfo
11// class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "HexagonRegisterInfo.h"
16#include "Hexagon.h"
17#include "HexagonMachineFunctionInfo.h"
18#include "HexagonSubtarget.h"
19#include "HexagonTargetMachine.h"
20#include "llvm/ADT/BitVector.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineFunctionPass.h"
25#include "llvm/CodeGen/MachineInstrBuilder.h"
26#include "llvm/CodeGen/MachineRegisterInfo.h"
27#include "llvm/CodeGen/PseudoSourceValue.h"
28#include "llvm/CodeGen/RegisterScavenging.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/Type.h"
31#include "llvm/MC/MachineLocation.h"
32#include "llvm/Support/CommandLine.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/raw_ostream.h"
36#include "llvm/Target/TargetInstrInfo.h"
37#include "llvm/Target/TargetMachine.h"
38#include "llvm/Target/TargetOptions.h"
39
40using namespace llvm;
41
42HexagonRegisterInfo::HexagonRegisterInfo()
43    : HexagonGenRegisterInfo(Hexagon::R31) {}
44
45
46bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
47  return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
48         R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
49}
50
51bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const {
52  return Hexagon::R16 <= Reg && Reg <= Hexagon::R27;
53}
54
55
56const MCPhysReg *
57HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF) const {
58  static const MCPhysReg CallerSavedRegsV4[] = {
59    Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
60    Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
61    Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
62    Hexagon::R15, 0
63  };
64
65  auto &HST = static_cast<const HexagonSubtarget&>(MF->getSubtarget());
66  switch (HST.getHexagonArchVersion()) {
67  case HexagonSubtarget::V4:
68  case HexagonSubtarget::V5:
69  case HexagonSubtarget::V55:
70  case HexagonSubtarget::V60:
71    return CallerSavedRegsV4;
72  }
73  llvm_unreachable(
74    "Callee saved registers requested for unknown archtecture version");
75}
76
77
78const MCPhysReg *
79HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
80  static const MCPhysReg CalleeSavedRegsV3[] = {
81    Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
82    Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
83    Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
84  };
85
86  switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
87  case HexagonSubtarget::V4:
88  case HexagonSubtarget::V5:
89  case HexagonSubtarget::V55:
90  case HexagonSubtarget::V60:
91    return CalleeSavedRegsV3;
92  }
93  llvm_unreachable("Callee saved registers requested for unknown architecture "
94                   "version");
95}
96
97BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
98  const {
99  BitVector Reserved(getNumRegs());
100  Reserved.set(HEXAGON_RESERVED_REG_1);
101  Reserved.set(HEXAGON_RESERVED_REG_2);
102  Reserved.set(Hexagon::R29);
103  Reserved.set(Hexagon::R30);
104  Reserved.set(Hexagon::R31);
105  Reserved.set(Hexagon::PC);
106  Reserved.set(Hexagon::GP);
107  Reserved.set(Hexagon::D14);
108  Reserved.set(Hexagon::D15);
109  Reserved.set(Hexagon::LC0);
110  Reserved.set(Hexagon::LC1);
111  Reserved.set(Hexagon::SA0);
112  Reserved.set(Hexagon::SA1);
113  return Reserved;
114}
115
116
117void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
118                                              int SPAdj, unsigned FIOp,
119                                              RegScavenger *RS) const {
120  //
121  // Hexagon_TODO: Do we need to enforce this for Hexagon?
122  assert(SPAdj == 0 && "Unexpected");
123
124  MachineInstr &MI = *II;
125  MachineBasicBlock &MB = *MI.getParent();
126  MachineFunction &MF = *MB.getParent();
127  auto &HST = MF.getSubtarget<HexagonSubtarget>();
128  auto &HII = *HST.getInstrInfo();
129  auto &HFI = *HST.getFrameLowering();
130
131  unsigned BP = 0;
132  int FI = MI.getOperand(FIOp).getIndex();
133  // Select the base pointer (BP) and calculate the actual offset from BP
134  // to the beginning of the object at index FI.
135  int Offset = HFI.getFrameIndexReference(MF, FI, BP);
136  // Add the offset from the instruction.
137  int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
138
139  unsigned Opc = MI.getOpcode();
140  switch (Opc) {
141    case Hexagon::TFR_FIA:
142      MI.setDesc(HII.get(Hexagon::A2_addi));
143      MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
144      MI.RemoveOperand(FIOp+1);
145      return;
146    case Hexagon::TFR_FI:
147      // Set up the instruction for updating below.
148      MI.setDesc(HII.get(Hexagon::A2_addi));
149      break;
150  }
151
152  if (HII.isValidOffset(Opc, RealOffset)) {
153    MI.getOperand(FIOp).ChangeToRegister(BP, false);
154    MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
155    return;
156  }
157
158#ifndef NDEBUG
159  const Function *F = MF.getFunction();
160  dbgs() << "In function ";
161  if (F) dbgs() << F->getName();
162  else   dbgs() << "<?>";
163  dbgs() << ", BB#" << MB.getNumber() << "\n" << MI;
164#endif
165  llvm_unreachable("Unhandled instruction");
166}
167
168
169unsigned HexagonRegisterInfo::getRARegister() const {
170  return Hexagon::R31;
171}
172
173
174unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
175                                               &MF) const {
176  const HexagonFrameLowering *TFI = getFrameLowering(MF);
177  if (TFI->hasFP(MF))
178    return getFrameRegister();
179  return getStackRegister();
180}
181
182
183unsigned HexagonRegisterInfo::getFrameRegister() const {
184  return Hexagon::R30;
185}
186
187
188unsigned HexagonRegisterInfo::getStackRegister() const {
189  return Hexagon::R29;
190}
191
192
193bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
194      const {
195  return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
196}
197
198
199unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
200  return Hexagon::R6;
201}
202
203
204#define GET_REGINFO_TARGET_DESC
205#include "HexagonGenRegisterInfo.inc"
206