1 //===- XtensaRegisterInfo.cpp - Xtensa Register Information ---------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the Xtensa implementation of the TargetRegisterInfo class.
11 //===----------------------------------------------------------------------===//
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"
25 #define DEBUG_TYPE "xtensa-reg-info"
27 #define GET_REGINFO_TARGET_DESC
28 #include "XtensaGenRegisterInfo.inc"
32 XtensaRegisterInfo::XtensaRegisterInfo(const XtensaSubtarget
&STI
)
33 : XtensaGenRegisterInfo(Xtensa::A0
), Subtarget(STI
) {}
36 XtensaRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
37 return CSR_Xtensa_SaveList
;
41 XtensaRegisterInfo::getCallPreservedMask(const MachineFunction
&MF
,
42 CallingConv::ID
) const {
43 return CSR_Xtensa_RegMask
;
46 BitVector
XtensaRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
47 BitVector
Reserved(getNumRegs());
48 const TargetFrameLowering
*TFI
= MF
.getSubtarget().getFrameLowering();
50 Reserved
.set(Xtensa::A0
);
52 // Reserve frame pointer.
53 Reserved
.set(getFrameRegister(MF
));
56 // Reserve stack pointer.
57 Reserved
.set(Xtensa::SP
);
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();
75 MinCSFI
= CSI
[0].getFrameIdx();
76 MaxCSFI
= CSI
[CSI
.size() - 1].getFrameIdx();
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.
86 if ((FrameIndex
>= MinCSFI
&& FrameIndex
<= MaxCSFI
))
87 FrameReg
= Xtensa::SP
;
89 FrameReg
= getFrameRegister(MF
);
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.
100 SPOffset
+ (int64_t)StackSize
+ MI
.getOperand(FIOperandNum
+ 1).getImm();
102 bool Valid
= isValidAddrOffset(MI
, Offset
);
104 // If MI is not a debug value, make sure Offset fits in the 16-bit immediate
106 if (!MI
.isDebugValue() && !Valid
) {
107 MachineBasicBlock
&MBB
= *MI
.getParent();
108 DebugLoc DL
= II
->getDebugLoc();
109 unsigned ADD
= Xtensa::ADD
;
111 const XtensaInstrInfo
&TII
= *static_cast<const XtensaInstrInfo
*>(
112 MBB
.getParent()->getSubtarget().getInstrInfo());
114 TII
.loadImmediate(MBB
, II
, &Reg
, Offset
);
115 BuildMI(MBB
, II
, DL
, TII
.get(ADD
), Reg
)
117 .addReg(Reg
, RegState::Kill
);
124 MI
.getOperand(FIOperandNum
).ChangeToRegister(FrameReg
, false, false, IsKill
);
125 MI
.getOperand(FIOperandNum
+ 1).ChangeToImmediate(Offset
);
130 Register
XtensaRegisterInfo::getFrameRegister(const MachineFunction
&MF
) const {
131 const TargetFrameLowering
*TFI
= MF
.getSubtarget().getFrameLowering();
132 return TFI
->hasFP(MF
) ? Xtensa::A15
: Xtensa::SP
;