23
23
24
24
using namespace llvm ;
25
25
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
+
26
32
XtensaFrameLowering::XtensaFrameLowering (const XtensaSubtarget &STI)
27
33
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4 ), 0,
28
- Align(4 )),
34
+ Align(4 )), STI(STI),
29
35
TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
30
36
31
37
bool XtensaFrameLowering::hasFPImpl (const MachineFunction &MF) const {
@@ -43,6 +49,7 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
43
49
MCRegister SP = Xtensa::SP;
44
50
MCRegister FP = TRI->getFrameRegister (MF);
45
51
const MCRegisterInfo *MRI = MF.getContext ().getRegisterInfo ();
52
+ XtensaMachineFunctionInfo *XtensaFI = MF.getInfo <XtensaMachineFunctionInfo>();
46
53
47
54
// First, compute final stack size.
48
55
uint64_t StackSize = MFI.getStackSize ();
@@ -51,6 +58,83 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
51
58
// Round up StackSize to 16*N
52
59
StackSize += (16 - StackSize) & 0xf ;
53
60
61
+ if (STI.isWinABI ()) {
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
+ unsigned TmpReg = Xtensa::A8;
74
+
75
+ const XtensaInstrInfo &TII = *static_cast <const XtensaInstrInfo *>(
76
+ MBB.getParent ()->getSubtarget ().getInstrInfo ());
77
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::ENTRY))
78
+ .addReg (SP)
79
+ .addImm (MIN_FRAME_SIZE);
80
+ TII.loadImmediate (MBB, MBBI, &TmpReg, StackSize - MIN_FRAME_SIZE);
81
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::SUB), TmpReg)
82
+ .addReg (SP)
83
+ .addReg (TmpReg);
84
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::MOVSP), SP).addReg (TmpReg);
85
+ }
86
+
87
+ // Calculate how much is needed to have the correct alignment.
88
+ // Change offset to: alignment + difference.
89
+ // For example, in case of alignment of 128:
90
+ // diff_to_128_aligned_address = (128 - (SP & 127))
91
+ // new_offset = SP + diff_to_128_aligned_address
92
+ // This is safe to do because we increased the stack size by MaxAlignment.
93
+ unsigned Reg, RegMisAlign;
94
+ if (MaxAlignment > 32 ){
95
+ TII.loadImmediate (MBB, MBBI, &RegMisAlign, MaxAlignment - 1 );
96
+ TII.loadImmediate (MBB, MBBI, &Reg, MaxAlignment);
97
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::AND))
98
+ .addReg (RegMisAlign, RegState::Define)
99
+ .addReg (FP)
100
+ .addReg (RegMisAlign);
101
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::SUB), RegMisAlign)
102
+ .addReg (Reg)
103
+ .addReg (RegMisAlign);
104
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::ADD), SP)
105
+ .addReg (SP)
106
+ .addReg (RegMisAlign, RegState::Kill);
107
+ }
108
+
109
+ // Store FP register in A8, because FP may be used to pass function
110
+ // arguments
111
+ if (XtensaFI->isSaveFrameRegister ()) {
112
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), Xtensa::A8)
113
+ .addReg (FP)
114
+ .addReg (FP);
115
+ }
116
+
117
+ // if framepointer enabled, set it to point to the stack pointer.
118
+ if (hasFP (MF)) {
119
+ // Insert instruction "move $fp, $sp" at this location.
120
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
121
+ .addReg (SP)
122
+ .addReg (SP)
123
+ .setMIFlag (MachineInstr::FrameSetup);
124
+
125
+ MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa (
126
+ nullptr , MRI->getDwarfRegNum (FP, true ), StackSize);
127
+ unsigned CFIIndex = MF.addFrameInst (Inst);
128
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
129
+ .addCFIIndex (CFIIndex);
130
+ } else {
131
+ // emit ".cfi_def_cfa_offset StackSize"
132
+ unsigned CFIIndex = MF.addFrameInst (
133
+ MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
134
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
135
+ .addCFIIndex (CFIIndex);
136
+ }
137
+ } else {
54
138
// No need to allocate space on the stack.
55
139
if (StackSize == 0 && !MFI.adjustsStack ())
56
140
return ;
@@ -122,6 +206,7 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
122
206
BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
123
207
.addCFIIndex (CFIIndex);
124
208
}
209
+ }
125
210
126
211
if (StackSize != PrevStackSize) {
127
212
MFI.setStackSize (StackSize);
@@ -179,10 +264,22 @@ void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
179
264
" Unexpected callee-saved register restore instruction" );
180
265
#endif
181
266
}
182
-
183
- BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
267
+ if (STI.isWinABI ()) {
268
+ // In most architectures, we need to explicitly restore the stack pointer
269
+ // before returning.
270
+ //
271
+ // For Xtensa Windowed Register option, it is not needed to explicitly
272
+ // restore the stack pointer. Reason being is that on function return,
273
+ // the window of the caller (including the old stack pointer) gets
274
+ // restored anyways.
275
+ } else {
276
+ BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
277
+ }
184
278
}
185
279
280
+ if (STI.isWinABI ())
281
+ return ;
282
+
186
283
// Get the number of bytes from FrameInfo
187
284
uint64_t StackSize = MFI.getStackSize ();
188
285
@@ -199,6 +296,9 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
199
296
MachineFunction *MF = MBB.getParent ();
200
297
MachineBasicBlock &EntryBlock = *(MF->begin ());
201
298
299
+ if (STI.isWinABI ())
300
+ return true ;
301
+
202
302
for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
203
303
// Add the callee-saved register as live-in. Do not add if the register is
204
304
// A0 and return address is taken, because it will be implemented in
@@ -224,6 +324,8 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
224
324
bool XtensaFrameLowering::restoreCalleeSavedRegisters (
225
325
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
226
326
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
327
+ if (STI.isWinABI ())
328
+ return true ;
227
329
return TargetFrameLowering::restoreCalleeSavedRegisters (MBB, MI, CSI, TRI);
228
330
}
229
331
@@ -251,6 +353,10 @@ void XtensaFrameLowering::determineCalleeSaves(MachineFunction &MF,
251
353
RegScavenger *RS) const {
252
354
unsigned FP = TRI->getFrameRegister (MF);
253
355
356
+ if (STI.isWinABI ()) {
357
+ return ;
358
+ }
359
+
254
360
TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
255
361
256
362
// Mark $fp as used if function has dedicated frame pointer.
0 commit comments