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
34
Align(4 )),
29
- TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
35
+ STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
30
36
31
37
bool XtensaFrameLowering::hasFPImpl (const MachineFunction &MF) const {
32
38
const MachineFrameInfo &MFI = MF.getFrameInfo ();
@@ -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,76 +58,153 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
51
58
// Round up StackSize to 16*N
52
59
StackSize += (16 - StackSize) & 0xf ;
53
60
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
+ }
80
84
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);
96
105
}
97
106
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
+ }
103
114
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));
106
132
BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
107
133
.addCFIIndex (CFIIndex);
108
134
}
109
- }
135
+ } else {
136
+ // No need to allocate space on the stack.
137
+ if (StackSize == 0 && !MFI.adjustsStack ())
138
+ return ;
110
139
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));
122
146
BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
123
147
.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
+ }
124
208
}
125
209
126
210
if (StackSize != PrevStackSize) {
@@ -179,10 +263,22 @@ void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
179
263
" Unexpected callee-saved register restore instruction" );
180
264
#endif
181
265
}
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
+ }
184
277
}
185
278
279
+ if (STI.isWindowedABI ())
280
+ return ;
281
+
186
282
// Get the number of bytes from FrameInfo
187
283
uint64_t StackSize = MFI.getStackSize ();
188
284
@@ -199,6 +295,9 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
199
295
MachineFunction *MF = MBB.getParent ();
200
296
MachineBasicBlock &EntryBlock = *(MF->begin ());
201
297
298
+ if (STI.isWindowedABI ())
299
+ return true ;
300
+
202
301
for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
203
302
// Add the callee-saved register as live-in. Do not add if the register is
204
303
// A0 and return address is taken, because it will be implemented in
@@ -224,16 +323,15 @@ bool XtensaFrameLowering::spillCalleeSavedRegisters(
224
323
bool XtensaFrameLowering::restoreCalleeSavedRegisters (
225
324
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
226
325
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
326
+ if (STI.isWindowedABI ())
327
+ return true ;
227
328
return TargetFrameLowering::restoreCalleeSavedRegisters (MBB, MI, CSI, TRI);
228
329
}
229
330
230
331
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
231
332
MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr (
232
333
MachineFunction &MF, MachineBasicBlock &MBB,
233
334
MachineBasicBlock::iterator I) const {
234
- const XtensaInstrInfo &TII =
235
- *static_cast <const XtensaInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
236
-
237
335
if (!hasReservedCallFrame (MF)) {
238
336
int64_t Amount = I->getOperand (0 ).getImm ();
239
337
@@ -249,7 +347,11 @@ MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(
249
347
void XtensaFrameLowering::determineCalleeSaves (MachineFunction &MF,
250
348
BitVector &SavedRegs,
251
349
RegScavenger *RS) const {
252
- unsigned FP = TRI->getFrameRegister (MF);
350
+ MCRegister FP = TRI->getFrameRegister (MF);
351
+
352
+ if (STI.isWindowedABI ()) {
353
+ return ;
354
+ }
253
355
254
356
TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
255
357
0 commit comments