XCoreRegisterInfo.cpp revision 1f375e5bc78647f9b29564eafdc907250ccd91ed
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//
2b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
3b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//                     The LLVM Compiler Infrastructure
4b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
5b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file is distributed under the University of Illinois Open Source
6b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// License. See LICENSE.TXT for details.
7b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
8b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
9b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
10b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file contains the XCore implementation of the MRegisterInfo class.
11b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
12b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
13b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
14b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreRegisterInfo.h"
15b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCore.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "XCoreMachineFunctionInfo.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/BitVector.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
19b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineFrameInfo.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunction.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h"
22b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineModuleInfo.h"
23b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineRegisterInfo.h"
24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/RegisterScavenging.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h"
27b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/Debug.h"
28804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h"
29804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/raw_ostream.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetFrameLowering.h"
31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h"
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h"
3473f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
3573f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC
36a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "XCoreGenRegisterInfo.inc"
3773f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
38b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm;
39b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
40b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii)
410e6a052331f674dd70e28af41f654a7874405eabEvan Cheng  : XCoreGenRegisterInfo(XCore::LR), TII(tii) {
42b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
43b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
44b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// helper functions
45b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool isImmUs(unsigned val) {
46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return val <= 11;
47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
49b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool isImmU6(unsigned val) {
50b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return val < (1 << 6);
51b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
52b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool isImmU16(unsigned val) {
54b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return val < (1 << 16);
55b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
56b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
57a267b0076e7887f5566e635ba35790f24d4524d9Chris Lattnerbool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
58fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola  return MF.getMMI().hasDebugInfo() ||
59fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola    MF.getFunction()->needsUnwindTableEntry();
60b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
61b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
62015f228861ef9b337366f92f637d4e8d624bb006Craig Topperconst uint16_t* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
63b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                                                                         const {
64015f228861ef9b337366f92f637d4e8d624bb006Craig Topper  static const uint16_t CalleeSavedRegs[] = {
65b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    XCore::R4, XCore::R5, XCore::R6, XCore::R7,
66b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    XCore::R8, XCore::R9, XCore::R10, XCore::LR,
67b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    0
68b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  };
69b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return CalleeSavedRegs;
70b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
71b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
72b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
73b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  BitVector Reserved(getNumRegs());
7416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
75d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
76b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Reserved.set(XCore::CP);
77b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Reserved.set(XCore::DP);
78b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Reserved.set(XCore::SP);
79b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Reserved.set(XCore::LR);
80d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF)) {
81b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    Reserved.set(XCore::R10);
82b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
83b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return Reserved;
84b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
85b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
86b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool
87b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
8816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
90d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  // TODO can we estimate stack size?
91d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF);
92b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
93b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
948ae8cf4559fc2e22fc0366f38533204718a9a32dRichard Osbornebool
956a8c7bf8e72338e55f0f9583e1828f62da165d4aPreston GurdXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
966a8c7bf8e72338e55f0f9583e1828f62da165d4aPreston Gurd  return requiresRegisterScavenging(MF);
976a8c7bf8e72338e55f0f9583e1828f62da165d4aPreston Gurd}
986a8c7bf8e72338e55f0f9583e1828f62da165d4aPreston Gurd
996a8c7bf8e72338e55f0f9583e1828f62da165d4aPreston Gurdbool
1008ae8cf4559fc2e22fc0366f38533204718a9a32dRichard OsborneXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
1018ae8cf4559fc2e22fc0366f38533204718a9a32dRichard Osborne  return false;
1028ae8cf4559fc2e22fc0366f38533204718a9a32dRichard Osborne}
1038ae8cf4559fc2e22fc0366f38533204718a9a32dRichard Osborne
104b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This function eliminates ADJCALLSTACKDOWN,
105b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// ADJCALLSTACKUP pseudo instructions
106b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreRegisterInfo::
107b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
108b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                              MachineBasicBlock::iterator I) const {
10916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
110d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
111d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
112b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
113b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
114b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    MachineInstr *Old = I;
115b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    uint64_t Amount = Old->getOperand(0).getImm();
116b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (Amount != 0) {
117b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // We need to keep the stack aligned properly.  To do this, we round the
118b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // amount of space needed for the outgoing arguments up to the next
119b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // alignment boundary.
12016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov      unsigned Align = TFI->getStackAlignment();
121b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      Amount = (Amount+Align-1)/Align*Align;
122b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
123b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      assert(Amount%4 == 0);
124b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      Amount /= 4;
12516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov
126b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      bool isU6 = isImmU6(Amount);
127b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      if (!isU6 && !isImmU16(Amount)) {
128b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        // FIX could emit multiple instructions in this case.
129dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
1304437ae213d5435390f0750213b53ec807c047f22Chris Lattner        errs() << "eliminateCallFramePseudoInstr size too big: "
1314437ae213d5435390f0750213b53ec807c047f22Chris Lattner               << Amount << "\n";
132dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
133c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable(0);
134b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      }
135b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
136b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      MachineInstr *New;
137b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
138b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
13921b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen        New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
140b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne          .addImm(Amount);
141b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      } else {
142b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
143b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
14421b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen        New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
145b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne          .addImm(Amount);
146b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      }
147b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
148b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // Replace the pseudo instruction with a new instruction...
149b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      MBB.insert(I, New);
150b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
151b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
152b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
153b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MBB.erase(I);
154b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
155b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
156fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
157b58f498f7502e7e1833decbbbb4df771367c7341Jim GrosbachXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
158fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                       int SPAdj, RegScavenger *RS) const {
159b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert(SPAdj == 0 && "Unexpected");
160b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineInstr &MI = *II;
161bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen  DebugLoc dl = MI.getDebugLoc();
162b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  unsigned i = 0;
163b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
164b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  while (!MI.getOperand(i).isFI()) {
165b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    ++i;
166b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
167b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
168b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
169b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineOperand &FrameOp = MI.getOperand(i);
170b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int FrameIndex = FrameOp.getIndex();
171b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
172b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineFunction &MF = *MI.getParent()->getParent();
17316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
174b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
175b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int StackSize = MF.getFrameInfo()->getStackSize();
176b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
177b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  #ifndef NDEBUG
178ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar  DEBUG(errs() << "\nFunction         : "
17996601ca332ab388754ca4673be8973396fea2dddCraig Topper        << MF.getName() << "\n");
180705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  DEBUG(errs() << "<--------->\n");
181705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  DEBUG(MI.print(errs()));
182705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");
183705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  DEBUG(errs() << "FrameOffset        : " << Offset << "\n");
184705e07f578e2b3af47ddab610feb4e7f2d3063a5Chris Lattner  DEBUG(errs() << "StackSize          : " << StackSize << "\n");
185b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  #endif
186b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
187b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Offset += StackSize;
188c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne
189c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne  unsigned FrameReg = getFrameRegister(MF);
190c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne
191c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne  // Special handling of DBG_VALUE instructions.
192c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne  if (MI.isDebugValue()) {
193c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne    MI.getOperand(i).ChangeToRegister(FrameReg, false /*isDef*/);
194c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne    MI.getOperand(i+1).ChangeToImmediate(Offset);
195c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne    return;
196c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne  }
197c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne
198b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // fold constant into offset.
199b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Offset += MI.getOperand(i + 1).getImm();
200b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MI.getOperand(i + 1).ChangeToImmediate(0);
201b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
202b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert(Offset%4 == 0 && "Misaligned stack offset");
203b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
204893e1c90a03a53cf13f73849324e83612688428aChris Lattner  DEBUG(errs() << "Offset             : " << Offset << "\n" << "<--------->\n");
205b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
206b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Offset/=4;
207b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
208d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  bool FP = TFI->hasFP(MF);
209c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne
21029cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  unsigned Reg = MI.getOperand(0).getReg();
21129cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill();
21229cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne
213420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
21429cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne
21529cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  MachineBasicBlock &MBB = *MI.getParent();
21629cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne
217b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (FP) {
218b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    bool isUs = isImmUs(Offset);
219b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
220b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (!isUs) {
2211bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer      if (!RS)
2221bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer        report_fatal_error("eliminateFrameIndex Frame size too big: " +
2231bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer                           Twine(Offset));
224420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      unsigned ScratchReg = RS->scavengeRegister(&XCore::GRRegsRegClass, II,
225b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                                                 SPAdj);
226bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen      loadConstant(MBB, II, ScratchReg, Offset, dl);
227b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      switch (MI.getOpcode()) {
22829cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::LDWFI:
229c2d98bc0d682419f09659d94afefd6a6266dd6eeDuncan Sands        BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
230c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
231587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling              .addReg(ScratchReg, RegState::Kill);
232b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
23329cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::STWFI:
2341f375e5bc78647f9b29564eafdc907250ccd91edRichard Osborne        BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
235587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling              .addReg(Reg, getKillRegState(isKill))
236c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
237587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling              .addReg(ScratchReg, RegState::Kill);
238b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
23929cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::LDAWFI:
240c2d98bc0d682419f09659d94afefd6a6266dd6eeDuncan Sands        BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
241c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
242587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling              .addReg(ScratchReg, RegState::Kill);
243b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
244b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      default:
245c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("Unexpected Opcode");
246b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      }
247b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    } else {
248b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      switch (MI.getOpcode()) {
24929cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::LDWFI:
250c2d98bc0d682419f09659d94afefd6a6266dd6eeDuncan Sands        BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
251c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
252b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne              .addImm(Offset);
253b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
25429cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::STWFI:
255c2d98bc0d682419f09659d94afefd6a6266dd6eeDuncan Sands        BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
256587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling              .addReg(Reg, getKillRegState(isKill))
257c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
258b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne              .addImm(Offset);
259b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
26029cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne      case XCore::LDAWFI:
261c2d98bc0d682419f09659d94afefd6a6266dd6eeDuncan Sands        BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
262c7e33965f0690d407d2ec2dc8036a58af94c0542Richard Osborne              .addReg(FrameReg)
263b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne              .addImm(Offset);
264b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        break;
265b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      default:
266c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("Unexpected Opcode");
267b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      }
268b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
269b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  } else {
270b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    bool isU6 = isImmU6(Offset);
2711bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer    if (!isU6 && !isImmU16(Offset))
2721bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer      report_fatal_error("eliminateFrameIndex Frame size too big: " +
2731bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer                         Twine(Offset));
274b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
27529cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne    switch (MI.getOpcode()) {
27629cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne    int NewOpcode;
27729cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne    case XCore::LDWFI:
278b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
279bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen      BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
28029cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne            .addImm(Offset);
281b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      break;
28229cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne    case XCore::STWFI:
283b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
284bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen      BuildMI(MBB, II, dl, TII.get(NewOpcode))
285587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling            .addReg(Reg, getKillRegState(isKill))
28629cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne            .addImm(Offset);
287b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      break;
28829cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne    case XCore::LDAWFI:
289b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
290bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen      BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
29129cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne            .addImm(Offset);
292b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      break;
293b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    default:
294c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      llvm_unreachable("Unexpected Opcode");
295b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
296b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
29729cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  // Erase old instruction.
29829cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  MBB.erase(II);
299b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
300b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
301b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreRegisterInfo::
302b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneloadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
303bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen            unsigned DstReg, int64_t Value, DebugLoc dl) const {
304b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // TODO use mkmsk if possible.
305b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (!isImmU16(Value)) {
306b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    // TODO use constant pool.
3071bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer    report_fatal_error("loadConstant value too big " + Twine(Value));
308b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
309b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
310bd9ef18f74a361e0ed630d373677c6fc0ce3cad9Dale Johannesen  BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value);
311b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
312b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
3133f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
31416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
316d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
317b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
318