Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp
96353 views
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
30
using namespace llvm;
31
32
XtensaRegisterInfo::XtensaRegisterInfo(const XtensaSubtarget &STI)
33
: XtensaGenRegisterInfo(Xtensa::A0), Subtarget(STI) {}
34
35
const uint16_t *
36
XtensaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37
return CSR_Xtensa_SaveList;
38
}
39
40
const uint32_t *
41
XtensaRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
42
CallingConv::ID) const {
43
return CSR_Xtensa_RegMask;
44
}
45
46
BitVector 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
61
bool 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(FIOperandNum).getIndex();
67
uint64_t StackSize = MF.getFrameInfo().getStackSize();
68
int64_t SPOffset = MF.getFrameInfo().getObjectOffset(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(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, II, &Reg, 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(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill);
125
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
126
127
return false;
128
}
129
130
Register XtensaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
131
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
132
return TFI->hasFP(MF) ? Xtensa::A15 : Xtensa::SP;
133
}
134
135