Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains XCore frame information that doesn't fit anywhere else
10
// cleanly...
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "XCoreFrameLowering.h"
15
#include "XCore.h"
16
#include "XCoreInstrInfo.h"
17
#include "XCoreMachineFunctionInfo.h"
18
#include "XCoreSubtarget.h"
19
#include "llvm/CodeGen/MachineFrameInfo.h"
20
#include "llvm/CodeGen/MachineFunction.h"
21
#include "llvm/CodeGen/MachineInstrBuilder.h"
22
#include "llvm/CodeGen/MachineModuleInfo.h"
23
#include "llvm/CodeGen/MachineRegisterInfo.h"
24
#include "llvm/CodeGen/RegisterScavenging.h"
25
#include "llvm/CodeGen/TargetLowering.h"
26
#include "llvm/IR/DataLayout.h"
27
#include "llvm/IR/Function.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Target/TargetOptions.h"
30
#include <algorithm> // std::sort
31
32
using namespace llvm;
33
34
static const unsigned FramePtr = XCore::R10;
35
static const int MaxImmU16 = (1<<16) - 1;
36
37
// helper functions. FIXME: Eliminate.
38
262
static inline bool isImmU6(unsigned val) {
39
262
  return val < (1 << 6);
40
262
}
41
42
0
static inline bool isImmU16(unsigned val) {
43
0
  return val < (1 << 16);
44
0
}
45
46
// Helper structure with compare function for handling stack slots.
47
namespace {
48
struct StackSlotInfo {
49
  int FI;
50
  int Offset;
51
  unsigned Reg;
52
84
  StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
53
};
54
}  // end anonymous namespace
55
56
20
static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
57
20
  return a.Offset < b.Offset;
58
20
}
59
60
static void EmitDefCfaRegister(MachineBasicBlock &MBB,
61
                               MachineBasicBlock::iterator MBBI,
62
                               const DebugLoc &dl, const TargetInstrInfo &TII,
63
9
                               MachineFunction &MF, unsigned DRegNum) {
64
9
  unsigned CFIIndex = MF.addFrameInst(
65
9
      MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
66
9
  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
67
9
      .addCFIIndex(CFIIndex);
68
9
}
69
70
static void EmitDefCfaOffset(MachineBasicBlock &MBB,
71
                             MachineBasicBlock::iterator MBBI,
72
                             const DebugLoc &dl, const TargetInstrInfo &TII,
73
58
                             int Offset) {
74
58
  MachineFunction &MF = *MBB.getParent();
75
58
  unsigned CFIIndex =
76
58
      MF.addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
77
58
  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
78
58
      .addCFIIndex(CFIIndex);
79
58
}
80
81
static void EmitCfiOffset(MachineBasicBlock &MBB,
82
                          MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
83
                          const TargetInstrInfo &TII, unsigned DRegNum,
84
132
                          int Offset) {
85
132
  MachineFunction &MF = *MBB.getParent();
86
132
  unsigned CFIIndex = MF.addFrameInst(
87
132
      MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
88
132
  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
89
132
      .addCFIIndex(CFIIndex);
90
132
}
91
92
/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
93
/// frame. During these steps, it may be necessary to spill registers.
94
/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
95
/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
96
/// \param OffsetFromTop the spill offset from the top of the frame.
97
/// \param [in,out] Adjusted the current SP offset from the top of the frame.
98
static void IfNeededExtSP(MachineBasicBlock &MBB,
99
                          MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
100
                          const TargetInstrInfo &TII, int OffsetFromTop,
101
303
                          int &Adjusted, int FrameSize, bool emitFrameMoves) {
102
321
  while (OffsetFromTop > Adjusted) {
103
18
    assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
104
18
    int remaining = FrameSize - Adjusted;
105
18
    int OpImm = (remaining > MaxImmU16) ? 
MaxImmU164
:
remaining14
;
106
18
    int Opcode = isImmU6(OpImm) ? 
XCore::EXTSP_u69
:
XCore::EXTSP_lu69
;
107
18
    BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
108
18
    Adjusted += OpImm;
109
18
    if (emitFrameMoves)
110
11
      EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
111
18
  }
112
303
}
113
114
/// The SP register is moved in steps of 'MaxImmU16' towards the top of the
115
/// frame. During these steps, it may be necessary to re-load registers.
116
/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
117
/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
118
/// \param OffsetFromTop the spill offset from the top of the frame.
119
/// \param [in,out] RemainingAdj the current SP offset from the top of the
120
/// frame.
121
static void IfNeededLDAWSP(MachineBasicBlock &MBB,
122
                           MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
123
                           const TargetInstrInfo &TII, int OffsetFromTop,
124
113
                           int &RemainingAdj) {
125
122
  while (OffsetFromTop < RemainingAdj - MaxImmU16) {
126
9
    assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
127
9
    int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : 
RemainingAdj0
;
128
9
    int Opcode = isImmU6(OpImm) ? 
XCore::LDAWSP_ru60
: XCore::LDAWSP_lru6;
129
9
    BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
130
9
    RemainingAdj -= OpImm;
131
9
  }
132
113
}
133
134
/// Creates an ordered list of registers that are spilled
135
/// during the emitPrologue/emitEpilogue.
136
/// Registers are ordered according to their frame offset.
137
/// As offsets are negative, the largest offsets will be first.
138
static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
139
                         MachineFrameInfo &MFI, XCoreFunctionInfo *XFI,
140
589
                         bool fetchLR, bool fetchFP) {
141
589
  if (fetchLR) {
142
7
    int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
143
7
    SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
144
7
                                      Offset,
145
7
                                      XCore::LR));
146
7
  }
147
589
  if (fetchFP) {
148
37
    int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
149
37
    SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
150
37
                                      Offset,
151
37
                                      FramePtr));
152
37
  }
153
589
  llvm::sort(SpillList, CompareSSIOffset);
154
589
}
155
156
/// Creates an ordered list of EH info register 'spills'.
157
/// These slots are only used by the unwinder and calls to llvm.eh.return().
158
/// Registers are ordered according to their frame offset.
159
/// As offsets are negative, the largest offsets will be first.
160
static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
161
                           MachineFrameInfo &MFI, XCoreFunctionInfo *XFI,
162
                           const Constant *PersonalityFn,
163
20
                           const TargetLowering *TL) {
164
20
  assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
165
20
  const int *EHSlot = XFI->getEHSpillSlot();
166
20
  SpillList.push_back(
167
20
      StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
168
20
                    TL->getExceptionPointerRegister(PersonalityFn)));
169
20
  SpillList.push_back(
170
20
      StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
171
20
                    TL->getExceptionSelectorRegister(PersonalityFn)));
172
20
  llvm::sort(SpillList, CompareSSIOffset);
173
20
}
174
175
static MachineMemOperand *getFrameIndexMMO(MachineBasicBlock &MBB,
176
                                           int FrameIndex,
177
60
                                           MachineMemOperand::Flags flags) {
178
60
  MachineFunction *MF = MBB.getParent();
179
60
  const MachineFrameInfo &MFI = MF->getFrameInfo();
180
60
  MachineMemOperand *MMO = MF->getMachineMemOperand(
181
60
      MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
182
60
      MFI.getObjectSize(FrameIndex), MFI.getObjectAlignment(FrameIndex));
183
60
  return MMO;
184
60
}
185
186
187
/// Restore clobbered registers with their spill slot value.
188
/// The SP will be adjusted at the same time, thus the SpillList must be ordered
189
/// with the largest (negative) offsets first.
190
static void RestoreSpillList(MachineBasicBlock &MBB,
191
                             MachineBasicBlock::iterator MBBI,
192
                             const DebugLoc &dl, const TargetInstrInfo &TII,
193
                             int &RemainingAdj,
194
318
                             SmallVectorImpl<StackSlotInfo> &SpillList) {
195
354
  for (unsigned i = 0, e = SpillList.size(); i != e; 
++i36
) {
196
36
    assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
197
36
    assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
198
36
    int OffsetFromTop = - SpillList[i].Offset/4;
199
36
    IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
200
36
    int Offset = RemainingAdj - OffsetFromTop;
201
36
    int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : 
XCore::LDWSP_lru60
;
202
36
    BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
203
36
      .addImm(Offset)
204
36
      .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
205
36
                                      MachineMemOperand::MOLoad));
206
36
  }
207
318
}
208
209
//===----------------------------------------------------------------------===//
210
// XCoreFrameLowering:
211
//===----------------------------------------------------------------------===//
212
213
XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
214
81
  : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
215
81
  // Do nothing
216
81
}
217
218
5.01k
bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
219
5.01k
  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
220
5.01k
         
MF.getFrameInfo().hasVarSizedObjects()4.56k
;
221
5.01k
}
222
223
void XCoreFrameLowering::emitPrologue(MachineFunction &MF,
224
280
                                      MachineBasicBlock &MBB) const {
225
280
  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
226
280
  MachineBasicBlock::iterator MBBI = MBB.begin();
227
280
  MachineFrameInfo &MFI = MF.getFrameInfo();
228
280
  MachineModuleInfo *MMI = &MF.getMMI();
229
280
  const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
230
280
  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
231
280
  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
232
280
  // Debug location must be unknown since the first debug location is used
233
280
  // to determine the end of the prologue.
234
280
  DebugLoc dl;
235
280
236
280
  if (MFI.getMaxAlignment() > getStackAlignment())
237
1
    report_fatal_error("emitPrologue unsupported alignment: "
238
1
                       + Twine(MFI.getMaxAlignment()));
239
279
240
279
  const AttributeList &PAL = MF.getFunction().getAttributes();
241
279
  if (PAL.hasAttrSomewhere(Attribute::Nest))
242
1
    BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
243
279
    // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
244
279
245
279
  // Work out frame sizes.
246
279
  // We will adjust the SP in stages towards the final FrameSize.
247
279
  assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
248
279
  const int FrameSize = MFI.getStackSize() / 4;
249
279
  int Adjusted = 0;
250
279
251
279
  bool saveLR = XFI->hasLRSpillSlot();
252
279
  bool UseENTSP = saveLR && 
FrameSize82
253
279
                  && 
(MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0)80
;
254
279
  if (UseENTSP)
255
78
    saveLR = false;
256
279
  bool FP = hasFP(MF);
257
279
  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
258
279
259
279
  if (UseENTSP) {
260
78
    // Allocate space on the stack at the same time as saving LR.
261
78
    Adjusted = (FrameSize > MaxImmU16) ? 
MaxImmU165
:
FrameSize73
;
262
78
    int Opcode = isImmU6(Adjusted) ? 
XCore::ENTSP_u662
:
XCore::ENTSP_lu616
;
263
78
    MBB.addLiveIn(XCore::LR);
264
78
    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
265
78
    MIB.addImm(Adjusted);
266
78
    MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
267
78
                           true);
268
78
    if (emitFrameMoves) {
269
47
      EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
270
47
      unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
271
47
      EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
272
47
    }
273
78
  }
274
279
275
279
  // If necessary, save LR and FP to the stack, as we EXTSP.
276
279
  SmallVector<StackSlotInfo,2> SpillList;
277
279
  GetSpillList(SpillList, MFI, XFI, saveLR, FP);
278
279
  // We want the nearest (negative) offsets first, so reverse list.
279
279
  std::reverse(SpillList.begin(), SpillList.end());
280
303
  for (unsigned i = 0, e = SpillList.size(); i != e; 
++i24
) {
281
24
    assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
282
24
    assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
283
24
    int OffsetFromTop = - SpillList[i].Offset/4;
284
24
    IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
285
24
                  emitFrameMoves);
286
24
    int Offset = Adjusted - OffsetFromTop;
287
24
    int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : 
XCore::STWSP_lru60
;
288
24
    MBB.addLiveIn(SpillList[i].Reg);
289
24
    BuildMI(MBB, MBBI, dl, TII.get(Opcode))
290
24
      .addReg(SpillList[i].Reg, RegState::Kill)
291
24
      .addImm(Offset)
292
24
      .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
293
24
                                      MachineMemOperand::MOStore));
294
24
    if (emitFrameMoves) {
295
9
      unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
296
9
      EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
297
9
    }
298
24
  }
299
279
300
279
  // Complete any remaining Stack adjustment.
301
279
  IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
302
279
                emitFrameMoves);
303
279
  assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
304
279
305
279
  if (FP) {
306
20
    // Set the FP from the SP.
307
20
    BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
308
20
    if (emitFrameMoves)
309
9
      EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
310
9
                         MRI->getDwarfRegNum(FramePtr, true));
311
20
  }
312
279
313
279
  if (emitFrameMoves) {
314
162
    // Frame moves for callee saved.
315
162
    for (const auto &SpillLabel : XFI->getSpillLabels()) {
316
52
      MachineBasicBlock::iterator Pos = SpillLabel.first;
317
52
      ++Pos;
318
52
      const CalleeSavedInfo &CSI = SpillLabel.second;
319
52
      int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
320
52
      unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
321
52
      EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
322
52
    }
323
162
    if (XFI->hasEHSpillSlot()) {
324
12
      // The unwinder requires stack slot & CFI offsets for the exception info.
325
12
      // We do not save/spill these registers.
326
12
      const Function *Fn = &MF.getFunction();
327
12
      const Constant *PersonalityFn =
328
12
          Fn->hasPersonalityFn() ? 
Fn->getPersonalityFn()0
: nullptr;
329
12
      SmallVector<StackSlotInfo, 2> SpillList;
330
12
      GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
331
12
                     MF.getSubtarget().getTargetLowering());
332
12
      assert(SpillList.size()==2 && "Unexpected SpillList size");
333
12
      EmitCfiOffset(MBB, MBBI, dl, TII,
334
12
                    MRI->getDwarfRegNum(SpillList[0].Reg, true),
335
12
                    SpillList[0].Offset);
336
12
      EmitCfiOffset(MBB, MBBI, dl, TII,
337
12
                    MRI->getDwarfRegNum(SpillList[1].Reg, true),
338
12
                    SpillList[1].Offset);
339
12
    }
340
162
  }
341
279
}
342
343
void XCoreFrameLowering::emitEpilogue(MachineFunction &MF,
344
318
                                     MachineBasicBlock &MBB) const {
345
318
  MachineFrameInfo &MFI = MF.getFrameInfo();
346
318
  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
347
318
  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
348
318
  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
349
318
  DebugLoc dl = MBBI->getDebugLoc();
350
318
  unsigned RetOpcode = MBBI->getOpcode();
351
318
352
318
  // Work out frame sizes.
353
318
  // We will adjust the SP in stages towards the final FrameSize.
354
318
  int RemainingAdj = MFI.getStackSize();
355
318
  assert(RemainingAdj%4 == 0 && "Misaligned frame size");
356
318
  RemainingAdj /= 4;
357
318
358
318
  if (RetOpcode == XCore::EH_RETURN) {
359
8
    // 'Restore' the exception info the unwinder has placed into the stack
360
8
    // slots.
361
8
    const Function *Fn = &MF.getFunction();
362
8
    const Constant *PersonalityFn =
363
8
        Fn->hasPersonalityFn() ? 
Fn->getPersonalityFn()0
: nullptr;
364
8
    SmallVector<StackSlotInfo, 2> SpillList;
365
8
    GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
366
8
                   MF.getSubtarget().getTargetLowering());
367
8
    RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
368
8
369
8
    // Return to the landing pad.
370
8
    unsigned EhStackReg = MBBI->getOperand(0).getReg();
371
8
    unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
372
8
    BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
373
8
    BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
374
8
    MBB.erase(MBBI);  // Erase the previous return instruction.
375
8
    return;
376
8
  }
377
310
378
310
  bool restoreLR = XFI->hasLRSpillSlot();
379
310
  bool UseRETSP = restoreLR && 
RemainingAdj72
380
310
                  && 
(MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0)70
;
381
310
  if (UseRETSP)
382
69
    restoreLR = false;
383
310
  bool FP = hasFP(MF);
384
310
385
310
  if (FP) // Restore the stack pointer.
386
17
    BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
387
310
388
310
  // If necessary, restore LR and FP from the stack, as we EXTSP.
389
310
  SmallVector<StackSlotInfo,2> SpillList;
390
310
  GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
391
310
  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
392
310
393
310
  if (RemainingAdj) {
394
77
    // Complete all but one of the remaining Stack adjustments.
395
77
    IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
396
77
    if (UseRETSP) {
397
69
      // Fold prologue into return instruction
398
69
      assert(RetOpcode == XCore::RETSP_u6
399
69
             || RetOpcode == XCore::RETSP_lu6);
400
69
      int Opcode = isImmU6(RemainingAdj) ? 
XCore::RETSP_u653
:
XCore::RETSP_lu616
;
401
69
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
402
69
                                  .addImm(RemainingAdj);
403
120
      for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; 
++i51
)
404
51
        MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
405
69
      MBB.erase(MBBI);  // Erase the previous return instruction.
406
69
    } else {
407
8
      int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
408
8
                                           
XCore::LDAWSP_lru60
;
409
8
      BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
410
8
      // Don't erase the return instruction.
411
8
    }
412
77
  } // else Don't erase the return instruction.
413
310
}
414
415
bool XCoreFrameLowering::
416
spillCalleeSavedRegisters(MachineBasicBlock &MBB,
417
                          MachineBasicBlock::iterator MI,
418
                          const std::vector<CalleeSavedInfo> &CSI,
419
21
                          const TargetRegisterInfo *TRI) const {
420
21
  if (CSI.empty())
421
0
    return true;
422
21
423
21
  MachineFunction *MF = MBB.getParent();
424
21
  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
425
21
  XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
426
21
  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
427
21
428
21
  DebugLoc DL;
429
21
  if (MI != MBB.end() && !MI->isDebugInstr())
430
21
    DL = MI->getDebugLoc();
431
21
432
21
  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
433
94
                                                    it != CSI.end(); 
++it73
) {
434
73
    unsigned Reg = it->getReg();
435
73
    assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
436
73
           "LR & FP are always handled in emitPrologue");
437
73
438
73
    // Add the callee-saved register as live-in. It's killed at the spill.
439
73
    MBB.addLiveIn(Reg);
440
73
    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
441
73
    TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
442
73
    if (emitFrameMoves) {
443
52
      auto Store = MI;
444
52
      --Store;
445
52
      XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
446
52
    }
447
73
  }
448
21
  return true;
449
21
}
450
451
bool XCoreFrameLowering::
452
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
453
                            MachineBasicBlock::iterator MI,
454
                            std::vector<CalleeSavedInfo> &CSI,
455
24
                            const TargetRegisterInfo *TRI) const{
456
24
  MachineFunction *MF = MBB.getParent();
457
24
  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
458
24
  bool AtStart = MI == MBB.begin();
459
24
  MachineBasicBlock::iterator BeforeI = MI;
460
24
  if (!AtStart)
461
20
    --BeforeI;
462
24
  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
463
113
                                                    it != CSI.end(); 
++it89
) {
464
89
    unsigned Reg = it->getReg();
465
89
    assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
466
89
           "LR & FP are always handled in emitEpilogue");
467
89
468
89
    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
469
89
    TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
470
89
    assert(MI != MBB.begin() &&
471
89
           "loadRegFromStackSlot didn't insert any code!");
472
89
    // Insert in reverse order.  loadRegFromStackSlot can insert multiple
473
89
    // instructions.
474
89
    if (AtStart)
475
19
      MI = MBB.begin();
476
70
    else {
477
70
      MI = BeforeI;
478
70
      ++MI;
479
70
    }
480
89
  }
481
24
  return true;
482
24
}
483
484
// This function eliminates ADJCALLSTACKDOWN,
485
// ADJCALLSTACKUP pseudo instructions
486
MachineBasicBlock::iterator XCoreFrameLowering::eliminateCallFramePseudoInstr(
487
    MachineFunction &MF, MachineBasicBlock &MBB,
488
144
    MachineBasicBlock::iterator I) const {
489
144
  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
490
144
  if (!hasReservedCallFrame(MF)) {
491
24
    // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
492
24
    // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
493
24
    MachineInstr &Old = *I;
494
24
    uint64_t Amount = Old.getOperand(0).getImm();
495
24
    if (Amount != 0) {
496
20
      // We need to keep the stack aligned properly.  To do this, we round the
497
20
      // amount of space needed for the outgoing arguments up to the next
498
20
      // alignment boundary.
499
20
      unsigned Align = getStackAlignment();
500
20
      Amount = (Amount+Align-1)/Align*Align;
501
20
502
20
      assert(Amount%4 == 0);
503
20
      Amount /= 4;
504
20
505
20
      bool isU6 = isImmU6(Amount);
506
20
      if (!isU6 && 
!isImmU16(Amount)0
) {
507
0
        // FIX could emit multiple instructions in this case.
508
#ifndef NDEBUG
509
        errs() << "eliminateCallFramePseudoInstr size too big: "
510
               << Amount << "\n";
511
#endif
512
0
        llvm_unreachable(nullptr);
513
0
      }
514
20
515
20
      MachineInstr *New;
516
20
      if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
517
10
        int Opcode = isU6 ? XCore::EXTSP_u6 : 
XCore::EXTSP_lu60
;
518
10
        New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
519
10
      } else {
520
10
        assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
521
10
        int Opcode = isU6 ? XCore::LDAWSP_ru6 : 
XCore::LDAWSP_lru60
;
522
10
        New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
523
10
                  .addImm(Amount);
524
10
      }
525
20
526
20
      // Replace the pseudo instruction with a new instruction...
527
20
      MBB.insert(I, New);
528
20
    }
529
24
  }
530
144
531
144
  return MBB.erase(I);
532
144
}
533
534
void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF,
535
                                              BitVector &SavedRegs,
536
282
                                              RegScavenger *RS) const {
537
282
  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
538
282
539
282
  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
540
282
541
282
  const MachineRegisterInfo &MRI = MF.getRegInfo();
542
282
  bool LRUsed = MRI.isPhysRegModified(XCore::LR);
543
282
544
282
  if (!LRUsed && 
!MF.getFunction().isVarArg()222
&&
545
282
      
MF.getFrameInfo().estimateStackSize(MF)220
)
546
16
    // If we need to extend the stack it is more efficient to use entsp / retsp.
547
16
    // We force the LR to be saved so these instructions are used.
548
16
    LRUsed = true;
549
282
550
282
  if (MF.callsUnwindInit() || 
MF.callsEHReturn()276
) {
551
12
    // The unwinder expects to find spill slots for the exception info regs R0
552
12
    // & R1. These are used during llvm.eh.return() to 'restore' the exception
553
12
    // info. N.B. we do not spill or restore R0, R1 during normal operation.
554
12
    XFI->createEHSpillSlot(MF);
555
12
    // As we will  have a stack, we force the LR to be saved.
556
12
    LRUsed = true;
557
12
  }
558
282
559
282
  if (LRUsed) {
560
82
    // We will handle the LR in the prologue/epilogue
561
82
    // and allocate space on the stack ourselves.
562
82
    SavedRegs.reset(XCore::LR);
563
82
    XFI->createLRSpillSlot(MF);
564
82
  }
565
282
566
282
  if (hasFP(MF))
567
20
    // A callee save register is used to hold the FP.
568
20
    // This needs saving / restoring in the epilogue / prologue.
569
20
    XFI->createFPSpillSlot(MF);
570
282
}
571
572
void XCoreFrameLowering::
573
processFunctionBeforeFrameFinalized(MachineFunction &MF,
574
280
                                    RegScavenger *RS) const {
575
280
  assert(RS && "requiresRegisterScavenging failed");
576
280
  MachineFrameInfo &MFI = MF.getFrameInfo();
577
280
  const TargetRegisterClass &RC = XCore::GRRegsRegClass;
578
280
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
579
280
  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
580
280
  // Reserve slots close to SP or frame pointer for Scavenging spills.
581
280
  // When using SP for small frames, we don't need any scratch registers.
582
280
  // When using SP for large frames, we may need 2 scratch registers.
583
280
  // When using FP, for large or small frames, we may need 1 scratch register.
584
280
  unsigned Size = TRI.getSpillSize(RC);
585
280
  unsigned Align = TRI.getSpillAlignment(RC);
586
280
  if (XFI->isLargeFrame(MF) || 
hasFP(MF)273
)
587
24
    RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
588
280
  if (XFI->isLargeFrame(MF) && 
!hasFP(MF)7
)
589
4
    RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
590
280
}