2323
2424using namespace llvm ;
2525
26+ // Minimum frame = reg save area (4 words) plus static chain (1 word)
27+ // and the total number of words must be a multiple of 128 bits.
28+ // Width of a word, in units (bytes).
29+ #define UNITS_PER_WORD 4
30+ #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
31+
2632XtensaFrameLowering::XtensaFrameLowering (const XtensaSubtarget &STI)
2733 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4 ), 0,
2834 Align(4 )),
29- TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
35+ STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
3036
3137bool XtensaFrameLowering::hasFPImpl (const MachineFunction &MF) const {
3238 const MachineFrameInfo &MFI = MF.getFrameInfo ();
@@ -43,6 +49,7 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
4349 MCRegister SP = Xtensa::SP;
4450 MCRegister FP = TRI->getFrameRegister (MF);
4551 const MCRegisterInfo *MRI = MF.getContext ().getRegisterInfo ();
52+ XtensaMachineFunctionInfo *XtensaFI = MF.getInfo <XtensaMachineFunctionInfo>();
4653
4754 // First, compute final stack size.
4855 uint64_t StackSize = MFI.getStackSize ();
@@ -51,76 +58,153 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
5158 // Round up StackSize to 16*N
5259 StackSize += (16 - StackSize) & 0xf ;
5360
54- // No need to allocate space on the stack.
55- if (StackSize == 0 && !MFI.adjustsStack ())
56- return ;
57-
58- // Adjust stack.
59- TII.adjustStackPtr (SP, -StackSize, MBB, MBBI);
60-
61- // emit ".cfi_def_cfa_offset StackSize"
62- unsigned CFIIndex =
63- MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
64- BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
65- .addCFIIndex (CFIIndex);
66-
67- const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
68-
69- if (!CSI.empty ()) {
70- // Find the instruction past the last instruction that saves a
71- // callee-saved register to the stack. The callee-saved store
72- // instructions are placed at the begin of basic block, so
73- // iterate over instruction sequence and check that
74- // save instructions are placed correctly.
75- for (unsigned i = 0 , e = CSI.size (); i < e; ++i) {
76- #ifndef NDEBUG
77- const CalleeSavedInfo &Info = CSI[i];
78- int FI = Info.getFrameIdx ();
79- int StoreFI = 0 ;
61+ if (STI.isWindowedABI ()) {
62+ StackSize += 32 ;
63+ uint64_t MaxAlignment = MFI.getMaxAlign ().value ();
64+ if (MaxAlignment > 32 )
65+ StackSize += MaxAlignment;
66+
67+ if (StackSize <= 32760 ) {
68+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::ENTRY))
69+ .addReg (SP)
70+ .addImm (StackSize);
71+ } else {
72+ // Use a8 as a temporary since a0-a7 may be live.
73+ MCRegister TmpReg = Xtensa::A8;
74+
75+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::ENTRY))
76+ .addReg (SP)
77+ .addImm (MIN_FRAME_SIZE);
78+ TII.loadImmediate (MBB, MBBI, &TmpReg, StackSize - MIN_FRAME_SIZE);
79+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::SUB), TmpReg)
80+ .addReg (SP)
81+ .addReg (TmpReg);
82+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::MOVSP), SP).addReg (TmpReg);
83+ }
8084
81- // Checking that the instruction is exactly as expected
82- bool IsStoreInst = false ;
83- if (MBBI->getOpcode () == TargetOpcode::COPY && Info.isSpilledToReg ()) {
84- Register DstReg = MBBI->getOperand (0 ).getReg ();
85- Register Reg = MBBI->getOperand (1 ).getReg ();
86- IsStoreInst = Info.getDstReg () == DstReg.asMCReg () &&
87- Info.getReg () == Reg.asMCReg ();
88- } else {
89- Register Reg = TII.isStoreToStackSlot (*MBBI, StoreFI);
90- IsStoreInst = Reg.asMCReg () == Info.getReg () && StoreFI == FI;
91- }
92- assert (IsStoreInst &&
93- " Unexpected callee-saved register store instruction" );
94- #endif
95- ++MBBI;
85+ // Calculate how much is needed to have the correct alignment.
86+ // Change offset to: alignment + difference.
87+ // For example, in case of alignment of 128:
88+ // diff_to_128_aligned_address = (128 - (SP & 127))
89+ // new_offset = SP + diff_to_128_aligned_address
90+ // This is safe to do because we increased the stack size by MaxAlignment.
91+ MCRegister Reg, RegMisAlign;
92+ if (MaxAlignment > 32 ) {
93+ TII.loadImmediate (MBB, MBBI, &RegMisAlign, MaxAlignment - 1 );
94+ TII.loadImmediate (MBB, MBBI, &Reg, MaxAlignment);
95+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::AND))
96+ .addReg (RegMisAlign, RegState::Define)
97+ .addReg (FP)
98+ .addReg (RegMisAlign);
99+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::SUB), RegMisAlign)
100+ .addReg (Reg)
101+ .addReg (RegMisAlign);
102+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::ADD), SP)
103+ .addReg (SP)
104+ .addReg (RegMisAlign, RegState::Kill);
96105 }
97106
98- // Iterate over list of callee-saved registers and emit .cfi_offset
99- // directives.
100- for (const auto &I : CSI) {
101- int64_t Offset = MFI.getObjectOffset (I.getFrameIdx ());
102- MCRegister Reg = I.getReg ();
107+ // Store FP register in A8, because FP may be used to pass function
108+ // arguments
109+ if (XtensaFI->isSaveFrameRegister ()) {
110+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), Xtensa::A8)
111+ .addReg (FP)
112+ .addReg (FP);
113+ }
103114
104- unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
105- nullptr , MRI->getDwarfRegNum (Reg, 1 ), Offset));
115+ // if framepointer enabled, set it to point to the stack pointer.
116+ if (hasFP (MF)) {
117+ // Insert instruction "move $fp, $sp" at this location.
118+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
119+ .addReg (SP)
120+ .addReg (SP)
121+ .setMIFlag (MachineInstr::FrameSetup);
122+
123+ MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa (
124+ nullptr , MRI->getDwarfRegNum (FP, true ), StackSize);
125+ unsigned CFIIndex = MF.addFrameInst (Inst);
126+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
127+ .addCFIIndex (CFIIndex);
128+ } else {
129+ // emit ".cfi_def_cfa_offset StackSize"
130+ unsigned CFIIndex = MF.addFrameInst (
131+ MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
106132 BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
107133 .addCFIIndex (CFIIndex);
108134 }
109- }
135+ } else {
136+ // No need to allocate space on the stack.
137+ if (StackSize == 0 && !MFI.adjustsStack ())
138+ return ;
110139
111- // if framepointer enabled, set it to point to the stack pointer.
112- if (hasFP (MF)) {
113- // Insert instruction "move $fp, $sp" at this location.
114- BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
115- .addReg (SP)
116- .addReg (SP)
117- .setMIFlag (MachineInstr::FrameSetup);
118-
119- // emit ".cfi_def_cfa_register $fp"
120- unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createDefCfaRegister (
121- nullptr , MRI->getDwarfRegNum (FP, true )));
140+ // Adjust stack.
141+ TII.adjustStackPtr (SP, -StackSize, MBB, MBBI);
142+
143+ // emit ".cfi_def_cfa_offset StackSize"
144+ unsigned CFIIndex =
145+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
122146 BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
123147 .addCFIIndex (CFIIndex);
148+
149+ const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
150+
151+ if (!CSI.empty ()) {
152+ // Find the instruction past the last instruction that saves a
153+ // callee-saved register to the stack. The callee-saved store
154+ // instructions are placed at the begin of basic block, so
155+ // iterate over instruction sequence and check that
156+ // save instructions are placed correctly.
157+ for (unsigned i = 0 , e = CSI.size (); i < e; ++i) {
158+ #ifndef NDEBUG
159+ const CalleeSavedInfo &Info = CSI[i];
160+ int FI = Info.getFrameIdx ();
161+ int StoreFI = 0 ;
162+
163+ // Checking that the instruction is exactly as expected
164+ bool IsStoreInst = false ;
165+ if (MBBI->getOpcode () == TargetOpcode::COPY && Info.isSpilledToReg ()) {
166+ Register DstReg = MBBI->getOperand (0 ).getReg ();
167+ Register Reg = MBBI->getOperand (1 ).getReg ();
168+ IsStoreInst = Info.getDstReg () == DstReg.asMCReg () &&
169+ Info.getReg () == Reg.asMCReg ();
170+ } else {
171+ Register Reg = TII.isStoreToStackSlot (*MBBI, StoreFI);
172+ IsStoreInst = Reg.asMCReg () == Info.getReg () && StoreFI == FI;
173+ }
174+ assert (IsStoreInst &&
175+ " Unexpected callee-saved register store instruction" );
176+ #endif
177+ ++MBBI;
178+ }
179+
180+ // Iterate over list of callee-saved registers and emit .cfi_offset
181+ // directives.
182+ for (const auto &I : CSI) {
183+ int64_t Offset = MFI.getObjectOffset (I.getFrameIdx ());
184+ MCRegister Reg = I.getReg ();
185+
186+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
187+ nullptr , MRI->getDwarfRegNum (Reg, 1 ), Offset));
188+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
189+ .addCFIIndex (CFIIndex);
190+ }
191+ }
192+
193+ // if framepointer enabled, set it to point to the stack pointer.
194+ if (hasFP (MF)) {
195+ // Insert instruction "move $fp, $sp" at this location.
196+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
197+ .addReg (SP)
198+ .addReg (SP)
199+ .setMIFlag (MachineInstr::FrameSetup);
200+
201+ // emit ".cfi_def_cfa_register $fp"
202+ unsigned CFIIndex =
203+ MF.addFrameInst (MCCFIInstruction::createDefCfaRegister (
204+ nullptr , MRI->getDwarfRegNum (FP, true )));
205+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
206+ .addCFIIndex (CFIIndex);
207+ }
124208 }
125209
126210 if (StackSize != PrevStackSize) {
@@ -179,10 +263,22 @@ void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
179263 " Unexpected callee-saved register restore instruction" );
180264#endif
181265 }
182-
183- BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
266+ if (STI.isWindowedABI ()) {
267+ // In most architectures, we need to explicitly restore the stack pointer
268+ // before returning.
269+ //
270+ // For Xtensa Windowed Register option, it is not needed to explicitly
271+ // restore the stack pointer. Reason being is that on function return,
272+ // the window of the caller (including the old stack pointer) gets
273+ // restored anyways.
274+ } else {
275+ BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
276+ }
184277 }
185278
279+ if (STI.isWindowedABI ())
280+ return ;
281+
186282 // Get the number of bytes from FrameInfo
187283 uint64_t StackSize = MFI.getStackSize ();
188284
@@ -199,6 +295,9 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
199295 MachineFunction *MF = MBB.getParent ();
200296 MachineBasicBlock &EntryBlock = *(MF->begin ());
201297
298+ if (STI.isWindowedABI ())
299+ return true ;
300+
202301 for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
203302 // Add the callee-saved register as live-in. Do not add if the register is
204303 // A0 and return address is taken, because it will be implemented in
@@ -224,16 +323,15 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
224323bool XtensaFrameLowering::restoreCalleeSavedRegisters (
225324 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
226325 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
326+ if (STI.isWindowedABI ())
327+ return true ;
227328 return TargetFrameLowering::restoreCalleeSavedRegisters (MBB, MI, CSI, TRI);
228329}
229330
230331// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
231332MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr (
232333 MachineFunction &MF, MachineBasicBlock &MBB,
233334 MachineBasicBlock::iterator I) const {
234- const XtensaInstrInfo &TII =
235- *static_cast <const XtensaInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
236-
237335 if (!hasReservedCallFrame (MF)) {
238336 int64_t Amount = I->getOperand (0 ).getImm ();
239337
@@ -249,7 +347,11 @@ MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(
249347void XtensaFrameLowering::determineCalleeSaves (MachineFunction &MF,
250348 BitVector &SavedRegs,
251349 RegScavenger *RS) const {
252- unsigned FP = TRI->getFrameRegister (MF);
350+ MCRegister FP = TRI->getFrameRegister (MF);
351+
352+ if (STI.isWindowedABI ()) {
353+ return ;
354+ }
253355
254356 TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
255357
0 commit comments