XCoreRegisterInfo.cpp revision 360784
1139804Simp//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//
2139013Sdavidxu//
3112904Sjeff// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4112904Sjeff// See https://llvm.org/LICENSE.txt for license information.
5112904Sjeff// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6112904Sjeff//
7112904Sjeff//===----------------------------------------------------------------------===//
8112904Sjeff//
9112904Sjeff// This file contains the XCore implementation of the MRegisterInfo class.
10112904Sjeff//
11112904Sjeff//===----------------------------------------------------------------------===//
12112904Sjeff
13112904Sjeff#include "XCoreRegisterInfo.h"
14112904Sjeff#include "XCore.h"
15112904Sjeff#include "XCoreInstrInfo.h"
16112904Sjeff#include "XCoreMachineFunctionInfo.h"
17112904Sjeff#include "XCoreSubtarget.h"
18112904Sjeff#include "llvm/ADT/BitVector.h"
19112904Sjeff#include "llvm/ADT/STLExtras.h"
20112904Sjeff#include "llvm/CodeGen/MachineFrameInfo.h"
21112904Sjeff#include "llvm/CodeGen/MachineFunction.h"
22112904Sjeff#include "llvm/CodeGen/MachineInstrBuilder.h"
23112904Sjeff#include "llvm/CodeGen/MachineModuleInfo.h"
24112904Sjeff#include "llvm/CodeGen/MachineRegisterInfo.h"
25112904Sjeff#include "llvm/CodeGen/RegisterScavenging.h"
26112904Sjeff#include "llvm/IR/Function.h"
27112904Sjeff#include "llvm/IR/Type.h"
28116182Sobrien#include "llvm/Support/Debug.h"
29116182Sobrien#include "llvm/Support/ErrorHandling.h"
30116182Sobrien#include "llvm/Support/MathExtras.h"
31162536Sdavidxu#include "llvm/Support/raw_ostream.h"
32112904Sjeff#include "llvm/CodeGen/TargetFrameLowering.h"
33112904Sjeff#include "llvm/Target/TargetMachine.h"
34131431Smarcel#include "llvm/Target/TargetOptions.h"
35112904Sjeff
36115765Sjeffusing namespace llvm;
37112904Sjeff
38164033Srwatson#define DEBUG_TYPE "xcore-reg-info"
39112904Sjeff
40161678Sdavidxu#define GET_REGINFO_TARGET_DESC
41161678Sdavidxu#include "XCoreGenRegisterInfo.inc"
42112904Sjeff
43112904SjeffXCoreRegisterInfo::XCoreRegisterInfo()
44112904Sjeff  : XCoreGenRegisterInfo(XCore::LR) {
45139013Sdavidxu}
46112904Sjeff
47112904Sjeff// helper functions
48139013Sdavidxustatic inline bool isImmUs(unsigned val) {
49139013Sdavidxu  return val <= 11;
50139013Sdavidxu}
51139013Sdavidxu
52139013Sdavidxustatic inline bool isImmU6(unsigned val) {
53139013Sdavidxu  return val < (1 << 6);
54162536Sdavidxu}
55162536Sdavidxu
56162536Sdavidxustatic inline bool isImmU16(unsigned val) {
57162536Sdavidxu  return val < (1 << 16);
58161678Sdavidxu}
59161678Sdavidxu
60161678Sdavidxu
61161678Sdavidxustatic void InsertFPImmInst(MachineBasicBlock::iterator II,
62161678Sdavidxu                            const XCoreInstrInfo &TII,
63161678Sdavidxu                            unsigned Reg, unsigned FrameReg, int Offset ) {
64139013Sdavidxu  MachineInstr &MI = *II;
65161678Sdavidxu  MachineBasicBlock &MBB = *MI.getParent();
66139013Sdavidxu  DebugLoc dl = MI.getDebugLoc();
67161678Sdavidxu
68139013Sdavidxu  switch (MI.getOpcode()) {
69161678Sdavidxu  case XCore::LDWFI:
70139013Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
71139013Sdavidxu          .addReg(FrameReg)
72139013Sdavidxu          .addImm(Offset)
73161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
74139013Sdavidxu    break;
75139013Sdavidxu  case XCore::STWFI:
76161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
77161678Sdavidxu          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
78139013Sdavidxu          .addReg(FrameReg)
79139013Sdavidxu          .addImm(Offset)
80161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
81161678Sdavidxu    break;
82139013Sdavidxu  case XCore::LDAWFI:
83139013Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
84139013Sdavidxu          .addReg(FrameReg)
85139013Sdavidxu          .addImm(Offset);
86161678Sdavidxu    break;
87161678Sdavidxu  default:
88161678Sdavidxu    llvm_unreachable("Unexpected Opcode");
89161678Sdavidxu  }
90161678Sdavidxu}
91161678Sdavidxu
92161678Sdavidxustatic void InsertFPConstInst(MachineBasicBlock::iterator II,
93161678Sdavidxu                              const XCoreInstrInfo &TII,
94161678Sdavidxu                              unsigned Reg, unsigned FrameReg,
95161678Sdavidxu                              int Offset, RegScavenger *RS ) {
96161678Sdavidxu  assert(RS && "requiresRegisterScavenging failed");
97161678Sdavidxu  MachineInstr &MI = *II;
98161678Sdavidxu  MachineBasicBlock &MBB = *MI.getParent();
99161678Sdavidxu  DebugLoc dl = MI.getDebugLoc();
100161678Sdavidxu  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
101161678Sdavidxu  RS->setRegUsed(ScratchOffset);
102161678Sdavidxu  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
103161678Sdavidxu
104161678Sdavidxu  switch (MI.getOpcode()) {
105161678Sdavidxu  case XCore::LDWFI:
106161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
107161678Sdavidxu          .addReg(FrameReg)
108115765Sjeff          .addReg(ScratchOffset, RegState::Kill)
109161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
110161678Sdavidxu    break;
111161678Sdavidxu  case XCore::STWFI:
112161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
113161678Sdavidxu          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
114161678Sdavidxu          .addReg(FrameReg)
115161678Sdavidxu          .addReg(ScratchOffset, RegState::Kill)
116161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
117161678Sdavidxu    break;
118161678Sdavidxu  case XCore::LDAWFI:
119161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
120161678Sdavidxu          .addReg(FrameReg)
121161678Sdavidxu          .addReg(ScratchOffset, RegState::Kill);
122161678Sdavidxu    break;
123161678Sdavidxu  default:
124161678Sdavidxu    llvm_unreachable("Unexpected Opcode");
125161678Sdavidxu  }
126161678Sdavidxu}
127161678Sdavidxu
128161678Sdavidxustatic void InsertSPImmInst(MachineBasicBlock::iterator II,
129161678Sdavidxu                            const XCoreInstrInfo &TII,
130161678Sdavidxu                            unsigned Reg, int Offset) {
131161678Sdavidxu  MachineInstr &MI = *II;
132161678Sdavidxu  MachineBasicBlock &MBB = *MI.getParent();
133161678Sdavidxu  DebugLoc dl = MI.getDebugLoc();
134161678Sdavidxu  bool isU6 = isImmU6(Offset);
135161742Sdavidxu
136161678Sdavidxu  switch (MI.getOpcode()) {
137115765Sjeff  int NewOpcode;
138115765Sjeff  case XCore::LDWFI:
139161678Sdavidxu    NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
140161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
141161678Sdavidxu          .addImm(Offset)
142138224Sdavidxu          .addMemOperand(*MI.memoperands_begin());
143161678Sdavidxu    break;
144161678Sdavidxu  case XCore::STWFI:
145161678Sdavidxu    NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
146161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(NewOpcode))
147161678Sdavidxu          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
148161678Sdavidxu          .addImm(Offset)
149161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
150161678Sdavidxu    break;
151161678Sdavidxu  case XCore::LDAWFI:
152161678Sdavidxu    NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
153158377Sdavidxu    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
154161678Sdavidxu          .addImm(Offset);
155161678Sdavidxu    break;
156161678Sdavidxu  default:
157138224Sdavidxu    llvm_unreachable("Unexpected Opcode");
158115765Sjeff  }
159161678Sdavidxu}
160161678Sdavidxu
161161678Sdavidxustatic void InsertSPConstInst(MachineBasicBlock::iterator II,
162161678Sdavidxu                                const XCoreInstrInfo &TII,
163161678Sdavidxu                                unsigned Reg, int Offset, RegScavenger *RS ) {
164161678Sdavidxu  assert(RS && "requiresRegisterScavenging failed");
165161678Sdavidxu  MachineInstr &MI = *II;
166161678Sdavidxu  MachineBasicBlock &MBB = *MI.getParent();
167161678Sdavidxu  DebugLoc dl = MI.getDebugLoc();
168161678Sdavidxu  unsigned OpCode = MI.getOpcode();
169161678Sdavidxu
170163709Sjb  unsigned ScratchBase;
171161678Sdavidxu  if (OpCode==XCore::STWFI) {
172161678Sdavidxu    ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
173161678Sdavidxu    RS->setRegUsed(ScratchBase);
174163709Sjb  } else
175163709Sjb    ScratchBase = Reg;
176163709Sjb  BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
177163709Sjb  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
178163709Sjb  RS->setRegUsed(ScratchOffset);
179161678Sdavidxu  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
180138224Sdavidxu
181138224Sdavidxu  switch (OpCode) {
182138224Sdavidxu  case XCore::LDWFI:
183115765Sjeff    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
184161678Sdavidxu          .addReg(ScratchBase, RegState::Kill)
185161678Sdavidxu          .addReg(ScratchOffset, RegState::Kill)
186161678Sdavidxu          .addMemOperand(*MI.memoperands_begin());
187161678Sdavidxu    break;
188161678Sdavidxu  case XCore::STWFI:
189161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
190161678Sdavidxu          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
191161678Sdavidxu          .addReg(ScratchBase, RegState::Kill)
192161678Sdavidxu          .addReg(ScratchOffset, RegState::Kill)
193138224Sdavidxu          .addMemOperand(*MI.memoperands_begin());
194161678Sdavidxu    break;
195115310Sjeff  case XCore::LDAWFI:
196161678Sdavidxu    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
197161678Sdavidxu          .addReg(ScratchBase, RegState::Kill)
198161678Sdavidxu          .addReg(ScratchOffset, RegState::Kill);
199161678Sdavidxu    break;
200161678Sdavidxu  default:
201161678Sdavidxu    llvm_unreachable("Unexpected Opcode");
202161678Sdavidxu  }
203139013Sdavidxu}
204139013Sdavidxu
205139257Sdavidxubool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
206139257Sdavidxu  return MF.needsFrameMoves();
207139013Sdavidxu}
208139013Sdavidxu
209161678Sdavidxuconst MCPhysReg *
210139257SdavidxuXCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
211139257Sdavidxu  // The callee saved registers LR & FP are explicitly handled during
212139013Sdavidxu  // emitPrologue & emitEpilogue and related functions.
213161678Sdavidxu  static const MCPhysReg CalleeSavedRegs[] = {
214139013Sdavidxu    XCore::R4, XCore::R5, XCore::R6, XCore::R7,
215139013Sdavidxu    XCore::R8, XCore::R9, XCore::R10,
216163697Sdavidxu    0
217161678Sdavidxu  };
218161678Sdavidxu  static const MCPhysReg CalleeSavedRegsFP[] = {
219161678Sdavidxu    XCore::R4, XCore::R5, XCore::R6, XCore::R7,
220161678Sdavidxu    XCore::R8, XCore::R9,
221161678Sdavidxu    0
222161678Sdavidxu  };
223115310Sjeff  const XCoreFrameLowering *TFI = getFrameLowering(*MF);
224161678Sdavidxu  if (TFI->hasFP(*MF))
225161678Sdavidxu    return CalleeSavedRegsFP;
226161678Sdavidxu  return CalleeSavedRegs;
227161678Sdavidxu}
228138224Sdavidxu
229161678SdavidxuBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
230161678Sdavidxu  BitVector Reserved(getNumRegs());
231161678Sdavidxu  const XCoreFrameLowering *TFI = getFrameLowering(MF);
232161678Sdavidxu
233161678Sdavidxu  Reserved.set(XCore::CP);
234161678Sdavidxu  Reserved.set(XCore::DP);
235161678Sdavidxu  Reserved.set(XCore::SP);
236161678Sdavidxu  Reserved.set(XCore::LR);
237161678Sdavidxu  if (TFI->hasFP(MF)) {
238161678Sdavidxu    Reserved.set(XCore::R10);
239161678Sdavidxu  }
240161678Sdavidxu  return Reserved;
241161678Sdavidxu}
242161678Sdavidxu
243143149Sdavidxubool
244143149SdavidxuXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
245143149Sdavidxu  return true;
246161678Sdavidxu}
247161678Sdavidxu
248161678Sdavidxubool
249161678SdavidxuXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
250161678Sdavidxu  return true;
251161678Sdavidxu}
252143149Sdavidxu
253143149Sdavidxubool
254143149SdavidxuXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
255143149Sdavidxu  return false;
256143149Sdavidxu}
257143149Sdavidxu
258143149Sdavidxuvoid
259143149SdavidxuXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
260161678Sdavidxu                                       int SPAdj, unsigned FIOperandNum,
261139013Sdavidxu                                       RegScavenger *RS) const {
262138224Sdavidxu  assert(SPAdj == 0 && "Unexpected");
263161678Sdavidxu  MachineInstr &MI = *II;
264161678Sdavidxu  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
265138224Sdavidxu  int FrameIndex = FrameOp.getIndex();
266138224Sdavidxu
267139013Sdavidxu  MachineFunction &MF = *MI.getParent()->getParent();
268139013Sdavidxu  const XCoreInstrInfo &TII =
269139013Sdavidxu      *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
270139013Sdavidxu
271161678Sdavidxu  const XCoreFrameLowering *TFI = getFrameLowering(MF);
272161678Sdavidxu  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
273139013Sdavidxu  int StackSize = MF.getFrameInfo().getStackSize();
274139013Sdavidxu
275161678Sdavidxu  #ifndef NDEBUG
276161678Sdavidxu  LLVM_DEBUG(errs() << "\nFunction         : " << MF.getName() << "\n");
277139013Sdavidxu  LLVM_DEBUG(errs() << "<--------->\n");
278161678Sdavidxu  LLVM_DEBUG(MI.print(errs()));
279139013Sdavidxu  LLVM_DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");
280139013Sdavidxu  LLVM_DEBUG(errs() << "FrameOffset        : " << Offset << "\n");
281161678Sdavidxu  LLVM_DEBUG(errs() << "StackSize          : " << StackSize << "\n");
282161678Sdavidxu#endif
283161678Sdavidxu
284161678Sdavidxu  Offset += StackSize;
285138224Sdavidxu
286139257Sdavidxu  Register FrameReg = getFrameRegister(MF);
287139257Sdavidxu
288161678Sdavidxu  // Special handling of DBG_VALUE instructions.
289139257Sdavidxu  if (MI.isDebugValue()) {
290161678Sdavidxu    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
291161678Sdavidxu    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
292161678Sdavidxu    return;
293161678Sdavidxu  }
294161678Sdavidxu
295161678Sdavidxu  // fold constant into offset.
296139257Sdavidxu  Offset += MI.getOperand(FIOperandNum + 1).getImm();
297161678Sdavidxu  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
298139257Sdavidxu
299139257Sdavidxu  assert(Offset%4 == 0 && "Misaligned stack offset");
300161678Sdavidxu  LLVM_DEBUG(errs() << "Offset             : " << Offset << "\n"
301161678Sdavidxu                    << "<--------->\n");
302161678Sdavidxu  Offset/=4;
303139257Sdavidxu
304139257Sdavidxu  Register Reg = MI.getOperand(0).getReg();
305139257Sdavidxu  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
306161678Sdavidxu
307139257Sdavidxu  if (TFI->hasFP(MF)) {
308161678Sdavidxu    if (isImmUs(Offset))
309161678Sdavidxu      InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
310161678Sdavidxu    else
311161678Sdavidxu      InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
312161678Sdavidxu  } else {
313161678Sdavidxu    if (isImmU16(Offset))
314139257Sdavidxu      InsertSPImmInst(II, TII, Reg, Offset);
315139257Sdavidxu    else
316161678Sdavidxu      InsertSPConstInst(II, TII, Reg, Offset, RS);
317161678Sdavidxu  }
318161678Sdavidxu  // Erase old instruction.
319139257Sdavidxu  MachineBasicBlock &MBB = *MI.getParent();
320139013Sdavidxu  MBB.erase(II);
321138224Sdavidxu}
322161678Sdavidxu
323161678Sdavidxu
324161678SdavidxuRegister XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
325161678Sdavidxu  const XCoreFrameLowering *TFI = getFrameLowering(MF);
326138224Sdavidxu
327138224Sdavidxu  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
328161678Sdavidxu}
329161678Sdavidxu