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::D15);
107  Reserved.set(Hexagon::LC0);
108  Reserved.set(Hexagon::LC1);
109  Reserved.set(Hexagon::SA0);
110  Reserved.set(Hexagon::SA1);
111  return Reserved;
112}
113
114
115void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
116                                              int SPAdj, unsigned FIOp,
117                                              RegScavenger *RS) const {
118  //
119  // Hexagon_TODO: Do we need to enforce this for Hexagon?
120  assert(SPAdj == 0 && "Unexpected");
121
122  MachineInstr &MI = *II;
123  MachineBasicBlock &MB = *MI.getParent();
124  MachineFunction &MF = *MB.getParent();
125  auto &HST = MF.getSubtarget<HexagonSubtarget>();
126  auto &HII = *HST.getInstrInfo();
127  auto &HFI = *HST.getFrameLowering();
128
129  unsigned BP = 0;
130  int FI = MI.getOperand(FIOp).getIndex();
131  // Select the base pointer (BP) and calculate the actual offset from BP
132  // to the beginning of the object at index FI.
133  int Offset = HFI.getFrameIndexReference(MF, FI, BP);
134  // Add the offset from the instruction.
135  int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
136
137  unsigned Opc = MI.getOpcode();
138  switch (Opc) {
139    case Hexagon::TFR_FIA:
140      MI.setDesc(HII.get(Hexagon::A2_addi));
141      MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
142      MI.RemoveOperand(FIOp+1);
143      return;
144    case Hexagon::TFR_FI:
145      // Set up the instruction for updating below.
146      MI.setDesc(HII.get(Hexagon::A2_addi));
147      break;
148  }
149
150  if (HII.isValidOffset(Opc, RealOffset)) {
151    MI.getOperand(FIOp).ChangeToRegister(BP, false);
152    MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
153    return;
154  }
155
156#ifndef NDEBUG
157  const Function *F = MF.getFunction();
158  dbgs() << "In function ";
159  if (F) dbgs() << F->getName();
160  else   dbgs() << "<?>";
161  dbgs() << ", BB#" << MB.getNumber() << "\n" << MI;
162#endif
163  llvm_unreachable("Unhandled instruction");
164}
165
166
167unsigned HexagonRegisterInfo::getRARegister() const {
168  return Hexagon::R31;
169}
170
171
172unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
173                                               &MF) const {
174  const HexagonFrameLowering *TFI = getFrameLowering(MF);
175  if (TFI->hasFP(MF))
176    return getFrameRegister();
177  return getStackRegister();
178}
179
180
181unsigned HexagonRegisterInfo::getFrameRegister() const {
182  return Hexagon::R30;
183}
184
185
186unsigned HexagonRegisterInfo::getStackRegister() const {
187  return Hexagon::R29;
188}
189
190
191bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
192      const {
193  return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
194}
195
196
197unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
198  return Hexagon::R6;
199}
200
201
202#define GET_REGINFO_TARGET_DESC
203#include "HexagonGenRegisterInfo.inc"
204