@@ -33,10 +33,158 @@ bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
33
33
}
34
34
35
35
void XtensaFrameLowering::emitPrologue (MachineFunction &MF,
36
- MachineBasicBlock &MBB) const {}
36
+ MachineBasicBlock &MBB) const {
37
+ assert (&MBB == &MF.front () && " Shrink-wrapping not yet implemented" );
38
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
39
+ const XtensaRegisterInfo *RegInfo = static_cast <const XtensaRegisterInfo *>(
40
+ MF.getSubtarget ().getRegisterInfo ());
41
+ const XtensaInstrInfo &TII =
42
+ *static_cast <const XtensaInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
43
+ MachineBasicBlock::iterator MBBI = MBB.begin ();
44
+ DebugLoc DL = MBBI != MBB.end () ? MBBI->getDebugLoc () : DebugLoc ();
45
+ unsigned SP = Xtensa::SP;
46
+ unsigned FP = RegInfo->getFrameRegister (MF);
47
+ MachineModuleInfo &MMI = MF.getMMI ();
48
+ const MCRegisterInfo *MRI = MMI.getContext ().getRegisterInfo ();
49
+
50
+ // First, compute final stack size.
51
+ uint64_t StackSize = MFI.getStackSize ();
52
+ uint64_t PrevStackSize = StackSize;
53
+
54
+ // Round up StackSize to 16*N
55
+ StackSize += (16 - StackSize) & 0xf ;
56
+
57
+ // No need to allocate space on the stack.
58
+ if (StackSize == 0 && !MFI.adjustsStack ())
59
+ return ;
60
+
61
+ // Adjust stack.
62
+ TII.adjustStackPtr (SP, -StackSize, MBB, MBBI);
63
+
64
+ // emit ".cfi_def_cfa_offset StackSize"
65
+ unsigned CFIIndex =
66
+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
67
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
68
+ .addCFIIndex (CFIIndex);
69
+
70
+ const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
71
+
72
+ if (CSI.size ()) {
73
+ // Find the instruction past the last instruction that saves a
74
+ // callee-saved register to the stack.
75
+ for (unsigned i = 0 ; i < CSI.size (); ++i)
76
+ ++MBBI;
77
+
78
+ // Iterate over list of callee-saved registers and emit .cfi_offset
79
+ // directives.
80
+ for (const auto &I : CSI) {
81
+ int64_t Offset = MFI.getObjectOffset (I.getFrameIdx ());
82
+ Register Reg = I.getReg ();
83
+
84
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
85
+ nullptr , MRI->getDwarfRegNum (Reg, 1 ), Offset));
86
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
87
+ .addCFIIndex (CFIIndex);
88
+ }
89
+ }
90
+
91
+ // if framepointer enabled, set it to point to the stack pointer.
92
+ if (hasFP (MF)) {
93
+ // Insert instruction "move $fp, $sp" at this location.
94
+ BuildMI (MBB, MBBI, DL, TII.get (Xtensa::OR), FP)
95
+ .addReg (SP)
96
+ .addReg (SP)
97
+ .setMIFlag (MachineInstr::FrameSetup);
98
+
99
+ // emit ".cfi_def_cfa_register $fp"
100
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createDefCfaRegister (
101
+ nullptr , MRI->getDwarfRegNum (FP, true )));
102
+ BuildMI (MBB, MBBI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
103
+ .addCFIIndex (CFIIndex);
104
+ }
105
+
106
+ if (StackSize != PrevStackSize) {
107
+ MFI.setStackSize (StackSize);
108
+
109
+ for (int i = MFI.getObjectIndexBegin (); i < MFI.getObjectIndexEnd (); i++) {
110
+ if (!MFI.isDeadObjectIndex (i)) {
111
+ int64_t SPOffset = MFI.getObjectOffset (i);
112
+
113
+ if (SPOffset < 0 )
114
+ MFI.setObjectOffset (i, SPOffset - StackSize + PrevStackSize);
115
+ }
116
+ }
117
+ }
118
+ }
37
119
38
120
void XtensaFrameLowering::emitEpilogue (MachineFunction &MF,
39
- MachineBasicBlock &MBB) const {}
121
+ MachineBasicBlock &MBB) const {
122
+ MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr ();
123
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
124
+ const XtensaRegisterInfo *RegInfo = static_cast <const XtensaRegisterInfo *>(
125
+ MF.getSubtarget ().getRegisterInfo ());
126
+ const XtensaInstrInfo &TII =
127
+ *static_cast <const XtensaInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
128
+ DebugLoc DL = MBBI->getDebugLoc ();
129
+ unsigned SP = Xtensa::SP;
130
+ unsigned FP = RegInfo->getFrameRegister (MF);
131
+
132
+ // if framepointer enabled, restore the stack pointer.
133
+ if (hasFP (MF)) {
134
+ // Find the first instruction that restores a callee-saved register.
135
+ MachineBasicBlock::iterator I = MBBI;
136
+
137
+ for (unsigned i = 0 ; i < MFI.getCalleeSavedInfo ().size (); ++i)
138
+ --I;
139
+
140
+ BuildMI (MBB, I, DL, TII.get (Xtensa::OR), SP).addReg (FP).addReg (FP);
141
+ }
142
+
143
+ // Get the number of bytes from FrameInfo
144
+ uint64_t StackSize = MFI.getStackSize ();
145
+
146
+ if (!StackSize)
147
+ return ;
148
+
149
+ // Adjust stack.
150
+ TII.adjustStackPtr (SP, StackSize, MBB, MBBI);
151
+ }
152
+
153
+ bool XtensaFrameLowering::spillCalleeSavedRegisters (
154
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
155
+ ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
156
+ MachineFunction *MF = MBB.getParent ();
157
+
158
+ MachineBasicBlock &EntryBlock = *(MF->begin ());
159
+ const TargetInstrInfo &TII = *MF->getSubtarget ().getInstrInfo ();
160
+
161
+ for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
162
+ // Add the callee-saved register as live-in. Do not add if the register is
163
+ // A0 and return address is taken, because it will be implemented in
164
+ // method XtensaTargetLowering::LowerRETURNADDR.
165
+ // It's killed at the spill, unless the register is RA and return address
166
+ // is taken.
167
+ Register Reg = CSI[i].getReg ();
168
+ bool IsA0AndRetAddrIsTaken =
169
+ (Reg == Xtensa::A0) && MF->getFrameInfo ().isReturnAddressTaken ();
170
+ if (!IsA0AndRetAddrIsTaken)
171
+ EntryBlock.addLiveIn (Reg);
172
+
173
+ // Insert the spill to the stack frame.
174
+ bool IsKill = !IsA0AndRetAddrIsTaken;
175
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass (Reg);
176
+ TII.storeRegToStackSlot (EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx (),
177
+ RC, TRI, Register ());
178
+ }
179
+
180
+ return true ;
181
+ }
182
+
183
+ bool XtensaFrameLowering::restoreCalleeSavedRegisters (
184
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
185
+ MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
186
+ return TargetFrameLowering::restoreCalleeSavedRegisters (MBB, MI, CSI, TRI);
187
+ }
40
188
41
189
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
42
190
MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr (
@@ -57,3 +205,31 @@ MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(
57
205
58
206
return MBB.erase (I);
59
207
}
208
+
209
+ void XtensaFrameLowering::determineCalleeSaves (MachineFunction &MF,
210
+ BitVector &SavedRegs,
211
+ RegScavenger *RS) const {
212
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
213
+ const XtensaRegisterInfo *RegInfo = static_cast <const XtensaRegisterInfo *>(
214
+ MF.getSubtarget ().getRegisterInfo ());
215
+ unsigned FP = RegInfo->getFrameRegister (MF);
216
+
217
+ TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
218
+
219
+ // Mark $fp as used if function has dedicated frame pointer.
220
+ if (hasFP (MF))
221
+ SavedRegs.set (FP);
222
+
223
+ // Set scavenging frame index if necessary.
224
+ uint64_t MaxSPOffset = MFI.estimateStackSize (MF);
225
+
226
+ if (isInt<12 >(MaxSPOffset))
227
+ return ;
228
+
229
+ const TargetRegisterClass &RC = Xtensa::ARRegClass;
230
+ const TargetRegisterInfo *TRI = MF.getSubtarget ().getRegisterInfo ();
231
+ unsigned Size = TRI->getSpillSize (RC);
232
+ Align Alignment = TRI->getSpillAlign (RC);
233
+ int FI = MF.getFrameInfo ().CreateStackObject (Size , Alignment, false );
234
+ RS->addScavengingFrameIndex (FI);
235
+ }
0 commit comments