1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains the Blackfin implementation of the TargetRegisterInfo
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// class.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Blackfin.h"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinRegisterInfo.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinSubtarget.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/RegisterScavenging.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetFrameLowering.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h"
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h"
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetInstrInfo.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Type.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/BitVector.h"
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/STLExtras.h"
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define GET_REGINFO_TARGET_DESC
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "BlackfinGenRegisterInfo.inc"
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           const TargetInstrInfo &tii)
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {}
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst unsigned*
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  using namespace BF;
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static const unsigned CalleeSavedRegs[] = {
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    FP,
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    R4, R5, R6, R7,
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    P3, P4, P5,
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    0 };
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return  CalleeSavedRegs;
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBitVector
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  using namespace BF;
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  BitVector Reserved(getNumRegs());
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AZ);
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AN);
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AQ);
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AC0);
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AC1);
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AV0);
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AV0S);
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AV1);
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(AV1S);
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(V);
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(VS);
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(CYCLES).set(CYCLES2);
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(L0);
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(L1);
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(L2);
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(L3);
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(SP);
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reserved.set(RETS);
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TFI->hasFP(MF))
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Reserved.set(FP);
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Reserved;
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool BlackfinRegisterInfo::
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanrequiresRegisterScavenging(const MachineFunction &MF) const {
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return true;
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit instructions to add delta to D/P register. ScratchReg must be of the
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// same class as Reg (P).
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB,
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          MachineBasicBlock::iterator I,
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          DebugLoc DL,
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          unsigned Reg,
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          unsigned ScratchReg,
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          int delta) const {
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!delta)
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return;
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (isInt<7>(delta)) {
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg)
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(Reg)              // No kill on two-addr operand
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addImm(delta);
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return;
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // We must load delta into ScratchReg and add that.
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  loadConstant(MBB, I, DL, ScratchReg, delta);
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (BF::PRegClass.contains(Reg)) {
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(BF::PRegClass.contains(ScratchReg) &&
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           "ScratchReg must be a P register");
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg)
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(Reg, RegState::Kill)
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(ScratchReg, RegState::Kill);
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register");
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(BF::DRegClass.contains(ScratchReg) &&
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           "ScratchReg must be a D register");
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg)
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(Reg, RegState::Kill)
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(ScratchReg, RegState::Kill);
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit instructions to load a constant into D/P register
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        MachineBasicBlock::iterator I,
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        DebugLoc DL,
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        unsigned Reg,
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        int value) const {
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (isInt<7>(value)) {
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value);
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return;
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (isUInt<16>(value)) {
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return;
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (isInt<16>(value)) {
138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return;
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // We must split into halves
143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  BuildMI(MBB, I, DL,
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    .addImm((value >> 16) & 0xffff)
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    .addReg(Reg, RegState::ImplicitDefine);
147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  BuildMI(MBB, I, DL,
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    .addImm(value & 0xffff)
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    .addReg(Reg, RegState::ImplicitKill)
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    .addReg(Reg, RegState::ImplicitDefine);
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo::
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumaneliminateCallFramePseudoInstr(MachineFunction &MF,
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                              MachineBasicBlock &MBB,
157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                              MachineBasicBlock::iterator I) const {
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TFI->hasReservedCallFrame(MF)) {
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int64_t Amount = I->getOperand(0).getImm();
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Amount != 0) {
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      assert(Amount%4 == 0 && "Unaligned call frame size");
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (I->getOpcode() == BF::ADJCALLSTACKDOWN) {
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount);
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else {
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        assert(I->getOpcode() == BF::ADJCALLSTACKUP &&
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               "Unknown call frame pseudo instruction");
169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount);
170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MBB.erase(I);
174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// findScratchRegister - Find a 'free' register. Try for a call-clobbered
177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// register first and then a spilled callee-saved register if that fails.
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic unsigned findScratchRegister(MachineBasicBlock::iterator II,
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    RegScavenger *RS,
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    const TargetRegisterClass *RC,
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    int SPAdj) {
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(RS && "Register scavenging must be on");
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Reg = RS->FindUnusedReg(RC);
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Reg == 0)
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Reg = RS->scavengeRegister(RC, II, SPAdj);
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Reg;
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          int SPAdj, RegScavenger *RS) const {
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MachineInstr &MI = *II;
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MachineBasicBlock &MBB = *MI.getParent();
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MachineFunction &MF = *MBB.getParent();
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc DL = MI.getDebugLoc();
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned FIPos;
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos < MI.getNumOperands() &&
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           "Instr doesn't have FrameIndex operand!");
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int FrameIndex = MI.getOperand(FIPos).getIndex();
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm());
205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex)
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    + MI.getOperand(FIPos+1).getImm();
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned BaseReg = BF::FP;
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TFI->hasFP(MF)) {
209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer");
210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BaseReg = BF::SP;
212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Offset += MF.getFrameInfo()->getStackSize() + SPAdj;
213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isStore = false;
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (MI.getOpcode()) {
218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::STORE32fi:
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    isStore = true;
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::LOAD32fi: {
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(Offset%4 == 0 && "Unaligned i32 stack access");
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos==1 && "Bad frame index operand");
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos+1).setImm(Offset);
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (isUInt<6>(Offset)) {
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MI.setDesc(TII.get(isStore
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         ? BF::STORE32p_uimm6m4
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         : BF::LOAD32p_uimm6m4));
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (BaseReg == BF::FP && isUInt<7>(-Offset)) {
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MI.setDesc(TII.get(isStore
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         ? BF::STORE32fp_nimm7m4
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         : BF::LOAD32fp_nimm7m4));
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MI.getOperand(FIPos+1).setImm(-Offset);
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (isInt<18>(Offset)) {
239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MI.setDesc(TII.get(isStore
240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         ? BF::STORE32p_imm18m4
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         : BF::LOAD32p_imm18m4));
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Use RegScavenger to calculate proper offset...
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.dump();
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    llvm_unreachable("Stack frame offset too big");
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::ADDpp: {
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(MI.getOperand(0).isReg() && "ADD instruction needs a register");
251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned DestReg = MI.getOperand(0).getReg();
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // We need to produce a stack offset in a P register. We emit:
253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // P0 = offset;
254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // P0 = BR + P0;
255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos==1 && "Bad frame index operand");
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    loadConstant(MBB, II, DL, DestReg, Offset);
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(1).ChangeToRegister(DestReg, false, false, true);
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(2).ChangeToRegister(BaseReg, false);
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::STORE16fi:
262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    isStore = true;
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::LOAD16fi: {
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(Offset%2 == 0 && "Unaligned i16 stack access");
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos==1 && "Bad frame index operand");
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // We need a P register to use as an address
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj);
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(ScratchReg && "Could not scavenge register");
269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    loadConstant(MBB, II, DL, ScratchReg, Offset);
270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg)
271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(ScratchReg, RegState::Kill)
272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      .addReg(BaseReg);
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi));
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true);
275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.RemoveOperand(2);
276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::STORE8fi: {
279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // This is an AnyCC spill, we need a scratch register.
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos==1 && "Bad frame index operand");
281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MachineOperand SpillReg = MI.getOperand(0);
282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(ScratchReg && "Could not scavenge register");
284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SpillReg.getReg()==BF::NCC) {
285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg)
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addOperand(SpillReg);
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg)
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addReg(ScratchReg).addImm(0);
289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg)
291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addOperand(SpillReg);
292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // STORE D
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.setDesc(TII.get(BF::STORE8p_imm16));
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true);
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos+1).setImm(Offset);
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case BF::LOAD8fi: {
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // This is an restore, we need a scratch register.
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(FIPos==1 && "Bad frame index operand");
303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MachineOperand SpillReg = MI.getOperand(0);
304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(ScratchReg && "Could not scavenge register");
306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.setDesc(TII.get(BF::LOAD32p_imm16_8z));
307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(0).ChangeToRegister(ScratchReg, true);
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MI.getOperand(FIPos+1).setImm(Offset);
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ++II;
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SpillReg.getReg()==BF::CC) {
312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // CC = D
313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC)
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addReg(ScratchReg, RegState::Kill);
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Restore NCC (CC = D==0)
317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC)
318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addReg(ScratchReg, RegState::Kill)
319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        .addImm(0);
320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    llvm_unreachable("Cannot eliminate frame index");
325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned
330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return TFI->hasFP(MF) ? BF::FP : BF::SP;
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  llvm_unreachable("What is the exception register");
338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return 0;
339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  llvm_unreachable("What is the exception handler register");
343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return 0;
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
345