1//===- XtensaRegisterInfo.cpp - Xtensa 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 Xtensa implementation of the TargetRegisterInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "XtensaRegisterInfo.h"
14#include "XtensaInstrInfo.h"
15#include "XtensaSubtarget.h"
16#include "XtensaUtils.h"
17#include "llvm/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/raw_ostream.h"
24
25#define DEBUG_TYPE "xtensa-reg-info"
26
27#define GET_REGINFO_TARGET_DESC
28#include "XtensaGenRegisterInfo.inc"
29
30using namespace llvm;
31
32XtensaRegisterInfo::XtensaRegisterInfo(const XtensaSubtarget &STI)
33 : XtensaGenRegisterInfo(Xtensa::A0), Subtarget(STI) {}
34
35const uint16_t *
36XtensaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37 return CSR_Xtensa_SaveList;
38}
39
40const uint32_t *
41XtensaRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
42 CallingConv::ID) const {
43 return CSR_Xtensa_RegMask;
44}
45
46BitVector XtensaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
47 BitVector Reserved(getNumRegs());
48 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
49
50 Reserved.set(Xtensa::A0);
51 if (TFI->hasFP(MF)) {
52 // Reserve frame pointer.
53 Reserved.set(getFrameRegister(MF));
54 }
55
56 // Reserve stack pointer.
57 Reserved.set(Xtensa::SP);
58 return Reserved;
59}
60
61bool XtensaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
62 int SPAdj, unsigned FIOperandNum,
63 RegScavenger *RS) const {
64 MachineInstr &MI = *II;
65 MachineFunction &MF = *MI.getParent()->getParent();
66 int FrameIndex = MI.getOperand(i: FIOperandNum).getIndex();
67 uint64_t StackSize = MF.getFrameInfo().getStackSize();
68 int64_t SPOffset = MF.getFrameInfo().getObjectOffset(ObjectIdx: FrameIndex);
69 MachineFrameInfo &MFI = MF.getFrameInfo();
70 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
71 int MinCSFI = 0;
72 int MaxCSFI = -1;
73
74 if (CSI.size()) {
75 MinCSFI = CSI[0].getFrameIdx();
76 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
77 }
78 // The following stack frame objects are always referenced relative to $sp:
79 // 1. Outgoing arguments.
80 // 2. Pointer to dynamically allocated stack space.
81 // 3. Locations for callee-saved registers.
82 // 4. Locations for eh data registers.
83 // Everything else is referenced relative to whatever register
84 // getFrameRegister() returns.
85 unsigned FrameReg;
86 if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
87 FrameReg = Xtensa::SP;
88 else
89 FrameReg = getFrameRegister(MF);
90
91 // Calculate final offset.
92 // - There is no need to change the offset if the frame object is one of the
93 // following: an outgoing argument, pointer to a dynamically allocated
94 // stack space or a $gp restore location,
95 // - If the frame object is any of the following, its offset must be adjusted
96 // by adding the size of the stack:
97 // incoming argument, callee-saved register location or local variable.
98 bool IsKill = false;
99 int64_t Offset =
100 SPOffset + (int64_t)StackSize + MI.getOperand(i: FIOperandNum + 1).getImm();
101
102 bool Valid = isValidAddrOffset(MI, Offset);
103
104 // If MI is not a debug value, make sure Offset fits in the 16-bit immediate
105 // field.
106 if (!MI.isDebugValue() && !Valid) {
107 MachineBasicBlock &MBB = *MI.getParent();
108 DebugLoc DL = II->getDebugLoc();
109 unsigned ADD = Xtensa::ADD;
110 unsigned Reg;
111 const XtensaInstrInfo &TII = *static_cast<const XtensaInstrInfo *>(
112 MBB.getParent()->getSubtarget().getInstrInfo());
113
114 TII.loadImmediate(MBB, MBBI: II, Reg: &Reg, Value: Offset);
115 BuildMI(MBB, II, DL, TII.get(ADD), Reg)
116 .addReg(FrameReg)
117 .addReg(Reg, RegState::Kill);
118
119 FrameReg = Reg;
120 Offset = 0;
121 IsKill = true;
122 }
123
124 MI.getOperand(i: FIOperandNum).ChangeToRegister(Reg: FrameReg, isDef: false, isImp: false, isKill: IsKill);
125 MI.getOperand(i: FIOperandNum + 1).ChangeToImmediate(ImmVal: Offset);
126
127 return false;
128}
129
130Register XtensaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
131 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
132 return TFI->hasFP(MF) ? Xtensa::A15 : Xtensa::SP;
133}
134

source code of llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp