1//===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the VE implementation of the TargetRegisterInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "VERegisterInfo.h"
14#include "VE.h"
15#include "VESubtarget.h"
16#include "llvm/ADT/BitVector.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/CodeGen/TargetInstrInfo.h"
23#include "llvm/IR/Type.h"
24#include "llvm/Support/CommandLine.h"
25#include "llvm/Support/ErrorHandling.h"
26
27using namespace llvm;
28
29#define GET_REGINFO_TARGET_DESC
30#include "VEGenRegisterInfo.inc"
31
32// VE uses %s10 == %lp to keep return address
33VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
34
35const MCPhysReg *
36VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37  switch (MF->getFunction().getCallingConv()) {
38  default:
39    return CSR_SaveList;
40  case CallingConv::PreserveAll:
41    return CSR_preserve_all_SaveList;
42  }
43}
44
45const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
46                                                     CallingConv::ID CC) const {
47  switch (CC) {
48  default:
49    return CSR_RegMask;
50  case CallingConv::PreserveAll:
51    return CSR_preserve_all_RegMask;
52  }
53}
54
55const uint32_t *VERegisterInfo::getNoPreservedMask() const {
56  return CSR_NoRegs_RegMask;
57}
58
59BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
60  BitVector Reserved(getNumRegs());
61
62  const Register ReservedRegs[] = {
63      VE::SX8,  // Stack limit
64      VE::SX9,  // Frame pointer
65      VE::SX10, // Link register (return address)
66      VE::SX11, // Stack pointer
67
68      // FIXME: maybe not need to be reserved
69      VE::SX12, // Outer register
70      VE::SX13, // Id register for dynamic linker
71
72      VE::SX14, // Thread pointer
73      VE::SX15, // Global offset table register
74      VE::SX16, // Procedure linkage table register
75      VE::SX17, // Linkage-area register
76                // sx18-sx33 are callee-saved registers
77                // sx34-sx63 are temporary registers
78  };
79
80  for (auto R : ReservedRegs)
81    for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
82         ++ItAlias)
83      Reserved.set(*ItAlias);
84
85  return Reserved;
86}
87
88bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { return false; }
89
90const TargetRegisterClass *
91VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
92                                   unsigned Kind) const {
93  return &VE::I64RegClass;
94}
95
96static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
97                      MachineInstr &MI, const DebugLoc &dl,
98                      unsigned FIOperandNum, int Offset, Register FrameReg) {
99  // Replace frame index with a frame pointer reference directly.
100  // VE has 32 bit offset field, so no need to expand a target instruction.
101  // Directly encode it.
102  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
103  MI.getOperand(FIOperandNum + 2).ChangeToImmediate(Offset);
104}
105
106void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
107                                         int SPAdj, unsigned FIOperandNum,
108                                         RegScavenger *RS) const {
109  assert(SPAdj == 0 && "Unexpected");
110
111  MachineInstr &MI = *II;
112  DebugLoc dl = MI.getDebugLoc();
113  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
114  MachineFunction &MF = *MI.getParent()->getParent();
115  const VEFrameLowering *TFI = getFrameLowering(MF);
116
117  Register FrameReg;
118  int Offset;
119  Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
120
121  Offset += MI.getOperand(FIOperandNum + 2).getImm();
122
123  replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
124}
125
126Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
127  return VE::SX9;
128}
129
130// VE has no architectural need for stack realignment support,
131// except that LLVM unfortunately currently implements overaligned
132// stack objects by depending upon stack realignment support.
133// If that ever changes, this can probably be deleted.
134bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
135  if (!TargetRegisterInfo::canRealignStack(MF))
136    return false;
137
138  // VE always has a fixed frame pointer register, so don't need to
139  // worry about needing to reserve it. [even if we don't have a frame
140  // pointer for our frame, it still cannot be used for other things,
141  // or register window traps will be SADNESS.]
142
143  // If there's a reserved call frame, we can use VE to access locals.
144  if (getFrameLowering(MF)->hasReservedCallFrame(MF))
145    return true;
146
147  // Otherwise, we'd need a base pointer, but those aren't implemented
148  // for VE at the moment.
149
150  return false;
151}
152