22
22
23
23
using namespace llvm ;
24
24
25
- XtensaFrameLowering::XtensaFrameLowering ()
25
+ XtensaFrameLowering::XtensaFrameLowering (const XtensaSubtarget &STI )
26
26
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4 ), 0,
27
- Align(4 )) {}
27
+ Align(4 )),
28
+ STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
28
29
29
30
bool XtensaFrameLowering::hasFP (const MachineFunction &MF) const {
30
31
const MachineFrameInfo &MFI = MF.getFrameInfo ();
@@ -33,10 +34,196 @@ bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
33
34
}
34
35
35
36
void XtensaFrameLowering::emitPrologue (MachineFunction &MF,
36
- MachineBasicBlock &MBB) const {}
37
+ MachineBasicBlock &MBB) const {
38
+ assert (&MBB == &MF.front () && " Shrink-wrapping not yet implemented" );
39
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
40
+ MachineBasicBlock::iterator MBBI = MBB.begin ();
41
+ DebugLoc DL = MBBI != MBB.end () ? MBBI->getDebugLoc () : DebugLoc ();
42
+ MCRegister SP = Xtensa::SP;
43
+ MCRegister FP = TRI->getFrameRegister (MF);
44
+ MachineModuleInfo &MMI = MF.getMMI ();
45
+ const MCRegisterInfo *MRI = MMI.getContext ().getRegisterInfo ();
46
+
47
+ // First, compute final stack size.
48
+ uint64_t StackSize = MFI.getStackSize ();
49
+ uint64_t PrevStackSize = StackSize;
50
+
51
+ // Round up StackSize to 16*N
52
+ StackSize += (16 - StackSize) & 0xf ;
53
+
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 ;
80
+
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) && (Info.getReg () == Reg);
87
+ } else {
88
+ Register Reg = TII.isStoreToStackSlot (*MBBI, StoreFI);
89
+ IsStoreInst = (Reg == Info.getReg ()) && (StoreFI == FI);
90
+ }
91
+ assert (IsStoreInst &&
92
+ " Unexpected callee-saved register store instruction" );
93
+ #endif
94
+ ++MBBI;
95
+ }
96
+
97
+ // Iterate over list of callee-saved registers and emit .cfi_offset
98
+ // directives.
99
+ for (const auto &I : CSI) {
100
+ int64_t Offset = MFI.getObjectOffset (I.getFrameIdx ());
101
+ Register Reg = I.getReg ();
102
+
103
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
104
+ nullptr , MRI->getDwarfRegNum (Reg, 1 ), Offset));
105
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
106
+ .addCFIIndex (CFIIndex);
107
+ }
108
+ }
109
+
110
+ // if framepointer enabled, set it to point to the stack pointer.
111
+ if (hasFP (MF)) {
112
+ // Insert instruction "move $fp, $sp" at this location.
113
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
114
+ .addReg (SP)
115
+ .addReg (SP)
116
+ .setMIFlag (MachineInstr::FrameSetup);
117
+
118
+ // emit ".cfi_def_cfa_register $fp"
119
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createDefCfaRegister (
120
+ nullptr , MRI->getDwarfRegNum (FP, true )));
121
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
122
+ .addCFIIndex (CFIIndex);
123
+ }
124
+
125
+ if (StackSize != PrevStackSize) {
126
+ MFI.setStackSize (StackSize);
127
+
128
+ for (int i = MFI.getObjectIndexBegin (); i < MFI.getObjectIndexEnd (); i++) {
129
+ if (!MFI.isDeadObjectIndex (i)) {
130
+ int64_t SPOffset = MFI.getObjectOffset (i);
131
+
132
+ if (SPOffset < 0 )
133
+ MFI.setObjectOffset (i, SPOffset - StackSize + PrevStackSize);
134
+ }
135
+ }
136
+ }
137
+ }
37
138
38
139
void XtensaFrameLowering::emitEpilogue (MachineFunction &MF,
39
- MachineBasicBlock &MBB) const {}
140
+ MachineBasicBlock &MBB) const {
141
+ MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr ();
142
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
143
+ DebugLoc DL = MBBI->getDebugLoc ();
144
+ MCRegister SP = Xtensa::SP;
145
+ MCRegister FP = TRI->getFrameRegister (MF);
146
+
147
+ // if framepointer enabled, restore the stack pointer.
148
+ if (hasFP (MF)) {
149
+ // We should place restore stack pointer instruction just before
150
+ // sequence of instructions which restores callee-saved registers.
151
+ // This sequence is placed at the end of the basic block,
152
+ // so we should find first instruction of the sequence.
153
+ MachineBasicBlock::iterator I = MBBI;
154
+
155
+ const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
156
+
157
+ // Find the first instruction at the end that restores a callee-saved
158
+ // register.
159
+ for (unsigned i = 0 , e = CSI.size (); i < e; ++i) {
160
+ --I;
161
+ #ifndef NDEBUG
162
+ const CalleeSavedInfo &Info = CSI[i];
163
+ int FI = Info.getFrameIdx ();
164
+ int LoadFI = 0 ;
165
+
166
+ // Checking that the instruction is exactly as expected
167
+ bool IsRestoreInst = false ;
168
+ if (I->getOpcode () == TargetOpcode::COPY && Info.isSpilledToReg ()) {
169
+ Register Reg = I->getOperand (0 ).getReg ();
170
+ Register DstReg = I->getOperand (1 ).getReg ();
171
+ IsRestoreInst = (Info.getDstReg () == DstReg) && (Info.getReg () == Reg);
172
+ } else {
173
+ Register Reg = TII.isLoadFromStackSlot (*I, LoadFI);
174
+ IsRestoreInst = (Info.getReg () == Reg) && (LoadFI == FI);
175
+ }
176
+ assert (IsRestoreInst &&
177
+ " Unexpected callee-saved register restore instruction" );
178
+ #endif
179
+ }
180
+
181
+ BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
182
+ }
183
+
184
+ // Get the number of bytes from FrameInfo
185
+ uint64_t StackSize = MFI.getStackSize ();
186
+
187
+ if (!StackSize)
188
+ return ;
189
+
190
+ // Adjust stack.
191
+ TII.adjustStackPtr (SP, StackSize, MBB, MBBI);
192
+ }
193
+
194
+ bool XtensaFrameLowering::spillCalleeSavedRegisters (
195
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
196
+ ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
197
+ MachineFunction *MF = MBB.getParent ();
198
+ MachineBasicBlock &EntryBlock = *(MF->begin ());
199
+
200
+ for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
201
+ // Add the callee-saved register as live-in. Do not add if the register is
202
+ // A0 and return address is taken, because it will be implemented in
203
+ // method XtensaTargetLowering::LowerRETURNADDR.
204
+ // It's killed at the spill, unless the register is RA and return address
205
+ // is taken.
206
+ Register Reg = CSI[i].getReg ();
207
+ bool IsA0AndRetAddrIsTaken =
208
+ (Reg == Xtensa::A0) && MF->getFrameInfo ().isReturnAddressTaken ();
209
+ if (!IsA0AndRetAddrIsTaken)
210
+ EntryBlock.addLiveIn (Reg);
211
+
212
+ // Insert the spill to the stack frame.
213
+ bool IsKill = !IsA0AndRetAddrIsTaken;
214
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass (Reg);
215
+ TII.storeRegToStackSlot (EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx (),
216
+ RC, TRI, Register ());
217
+ }
218
+
219
+ return true ;
220
+ }
221
+
222
+ bool XtensaFrameLowering::restoreCalleeSavedRegisters (
223
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
224
+ MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
225
+ return TargetFrameLowering::restoreCalleeSavedRegisters (MBB, MI, CSI, TRI);
226
+ }
40
227
41
228
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
42
229
MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr (
@@ -51,9 +238,37 @@ MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(
51
238
if (I->getOpcode () == Xtensa::ADJCALLSTACKDOWN)
52
239
Amount = -Amount;
53
240
54
- unsigned SP = Xtensa::SP;
55
- TII.adjustStackPtr (SP, Amount, MBB, I);
241
+ TII.adjustStackPtr (Xtensa::SP, Amount, MBB, I);
56
242
}
57
243
58
244
return MBB.erase (I);
59
245
}
246
+
247
+ void XtensaFrameLowering::determineCalleeSaves (MachineFunction &MF,
248
+ BitVector &SavedRegs,
249
+ RegScavenger *RS) const {
250
+ unsigned FP = TRI->getFrameRegister (MF);
251
+
252
+ TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
253
+
254
+ // Mark $fp as used if function has dedicated frame pointer.
255
+ if (hasFP (MF))
256
+ SavedRegs.set (FP);
257
+ }
258
+
259
+ void XtensaFrameLowering::processFunctionBeforeFrameFinalized (
260
+ MachineFunction &MF, RegScavenger *RS) const {
261
+ // Set scavenging frame index if necessary.
262
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
263
+ uint64_t MaxSPOffset = MFI.estimateStackSize (MF);
264
+
265
+ if (isInt<12 >(MaxSPOffset))
266
+ return ;
267
+
268
+ const TargetRegisterClass &RC = Xtensa::ARRegClass;
269
+ unsigned Size = TRI->getSpillSize (RC);
270
+ Align Alignment = TRI->getSpillAlign (RC);
271
+ int FI = MF.getFrameInfo ().CreateStackObject (Size , Alignment, false );
272
+
273
+ RS->addScavengingFrameIndex (FI);
274
+ }
0 commit comments