LLVM 22.0.0git
XtensaRegisterInfo.cpp
Go to the documentation of this file.
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"
15#include "XtensaInstrInfo.h"
16#include "XtensaSubtarget.h"
21#include "llvm/Support/Debug.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
34
35const uint16_t *
37 return Subtarget.isWindowedABI() ? CSRW8_Xtensa_SaveList
38 : CSR_Xtensa_SaveList;
39}
40
41const uint32_t *
43 CallingConv::ID) const {
44 return Subtarget.isWindowedABI() ? CSRW8_Xtensa_RegMask : CSR_Xtensa_RegMask;
45}
46
48 BitVector Reserved(getNumRegs());
50
51 Reserved.set(Xtensa::A0);
52 if (TFI->hasFP(MF)) {
53 // Reserve frame pointer.
55 }
56 if (Subtarget.hasTHREADPTR()) {
57 // Reserve frame pointer.
58 Reserved.set(Xtensa::THREADPTR);
59 }
60 // Reserve stack pointer.
61 Reserved.set(Xtensa::SP);
62 return Reserved;
63}
64
66 int SPAdj, unsigned FIOperandNum,
67 RegScavenger *RS) const {
68 MachineInstr &MI = *II;
69 MachineFunction &MF = *MI.getParent()->getParent();
70 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
71 uint64_t StackSize = MF.getFrameInfo().getStackSize();
72 int64_t SPOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);
74 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
75 int MinCSFI = 0;
76 int MaxCSFI = -1;
77
78 if (CSI.size()) {
79 MinCSFI = CSI[0].getFrameIdx();
80 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
81 }
82 // The following stack frame objects are always referenced relative to $sp:
83 // 1. Outgoing arguments.
84 // 2. Pointer to dynamically allocated stack space.
85 // 3. Locations for callee-saved registers.
86 // 4. Locations for eh data registers.
87 // Everything else is referenced relative to whatever register
88 // getFrameRegister() returns.
89 MCRegister FrameReg;
90 if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
91 FrameReg = Xtensa::SP;
92 else
93 FrameReg = getFrameRegister(MF);
94
95 // Calculate final offset.
96 // - There is no need to change the offset if the frame object is one of the
97 // following: an outgoing argument, pointer to a dynamically allocated
98 // stack space or a $gp restore location,
99 // - If the frame object is any of the following, its offset must be adjusted
100 // by adding the size of the stack:
101 // incoming argument, callee-saved register location or local variable.
102 bool IsKill = false;
103 int64_t Offset =
104 SPOffset + (int64_t)StackSize + MI.getOperand(FIOperandNum + 1).getImm();
105
106 bool Valid = Xtensa::isValidAddrOffsetForOpcode(MI.getOpcode(), Offset);
107
108 // If MI is not a debug value, make sure Offset fits in the 16-bit immediate
109 // field.
110 if (!MI.isDebugValue() && !Valid) {
111 MachineBasicBlock &MBB = *MI.getParent();
112 DebugLoc DL = II->getDebugLoc();
113 unsigned ADD = Xtensa::ADD;
114 MCRegister Reg;
115 const XtensaInstrInfo &TII = *static_cast<const XtensaInstrInfo *>(
116 MBB.getParent()->getSubtarget().getInstrInfo());
117
118 TII.loadImmediate(MBB, II, &Reg, Offset);
119 BuildMI(MBB, II, DL, TII.get(ADD), Reg)
120 .addReg(FrameReg)
121 .addReg(Reg, RegState::Kill);
122
123 FrameReg = Reg;
124 Offset = 0;
125 IsKill = true;
126 }
127
128 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill);
129 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
130
131 return false;
132}
133
136 return TFI->hasFP(MF) ? (Subtarget.isWindowedABI() ? Xtensa::A7 : Xtensa::A15)
137 : Xtensa::SP;
138}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
uint64_t IntrinsicInst * II
A debug info location.
Definition DebugLoc.h:124
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Wrapper class representing virtual and physical registers.
Definition Register.h:19
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual const TargetFrameLowering * getFrameLowering() const
XtensaRegisterInfo(const XtensaSubtarget &STI)
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const override
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const XtensaSubtarget & Subtarget
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register getFrameRegister(const MachineFunction &MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Kill
The last use of a register.
bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.