1d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===//
2d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//
3d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//                     The LLVM Compiler Infrastructure
4d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//
5d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// This file is distributed under the University of Illinois Open Source
6d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// License. See LICENSE.TXT for details.
7d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//
8d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===----------------------------------------------------------------------===//
9d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//
10d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// This file contains the Blackfin implementation of the TargetRegisterInfo
11d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// class.
12d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//
13d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===----------------------------------------------------------------------===//
14d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
15d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "Blackfin.h"
16d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "BlackfinRegisterInfo.h"
17d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "BlackfinSubtarget.h"
18d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Support/Debug.h"
19d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Support/ErrorHandling.h"
20d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineInstrBuilder.h"
21d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFunction.h"
22d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFrameInfo.h"
23d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/RegisterScavenging.h"
2416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h"
25d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetMachine.h"
26d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetOptions.h"
27d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetInstrInfo.h"
28d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Type.h"
29d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/ADT/BitVector.h"
30d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/ADT/STLExtras.h"
3173f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
3273f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC
33a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "BlackfinGenRegisterInfo.inc"
3473f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
35d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenusing namespace llvm;
36d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
37d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
38d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                           const TargetInstrInfo &tii)
390e6a052331f674dd70e28af41f654a7874405eabEvan Cheng  : BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {}
40d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
41d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenconst unsigned*
42d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
43d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  using namespace BF;
44d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  static const unsigned CalleeSavedRegs[] = {
45d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    FP,
46d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    R4, R5, R6, R7,
47d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    P3, P4, P5,
48d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    0 };
49d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return  CalleeSavedRegs;
50d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
51d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
52d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBitVector
53d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
5416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
56d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  using namespace BF;
57d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  BitVector Reserved(getNumRegs());
5871d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AZ);
5971d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AN);
6071d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AQ);
6171d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AC0);
6271d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AC1);
6371d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AV0);
6471d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AV0S);
6571d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AV1);
6671d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(AV1S);
6771d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(V);
6871d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen  Reserved.set(VS);
6946151de6a0d08184c1bfc90bb39657ff1e21729eJakob Stoklund Olesen  Reserved.set(CYCLES).set(CYCLES2);
70d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(L0);
71d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(L1);
72d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(L2);
73d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(L3);
74d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(SP);
75d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  Reserved.set(RETS);
76d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
77d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    Reserved.set(FP);
78d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return Reserved;
79d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
80d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
81d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenbool BlackfinRegisterInfo::
82d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenrequiresRegisterScavenging(const MachineFunction &MF) const {
83d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return true;
84d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
85d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
86d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// Emit instructions to add delta to D/P register. ScratchReg must be of the
87d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// same class as Reg (P).
88d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB,
89d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                          MachineBasicBlock::iterator I,
90d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                          DebugLoc DL,
91d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                          unsigned Reg,
92d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                          unsigned ScratchReg,
93d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                          int delta) const {
94d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  if (!delta)
95d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    return;
96d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen  if (isInt<7>(delta)) {
97d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg)
98d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(Reg)              // No kill on two-addr operand
99d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addImm(delta);
100d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    return;
101d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
102d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
103d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  // We must load delta into ScratchReg and add that.
104d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  loadConstant(MBB, I, DL, ScratchReg, delta);
105d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  if (BF::PRegClass.contains(Reg)) {
106ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(BF::PRegClass.contains(ScratchReg) &&
107ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen           "ScratchReg must be a P register");
108d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg)
109d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(Reg, RegState::Kill)
110d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(ScratchReg, RegState::Kill);
111d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  } else {
112ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register");
113ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(BF::DRegClass.contains(ScratchReg) &&
114ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen           "ScratchReg must be a D register");
115d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg)
116d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(Reg, RegState::Kill)
117d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(ScratchReg, RegState::Kill);
118d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
119d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
120d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
121d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// Emit instructions to load a constant into D/P register
122d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
123d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                        MachineBasicBlock::iterator I,
124d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                        DebugLoc DL,
125d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                        unsigned Reg,
126d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                        int value) const {
127d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen  if (isInt<7>(value)) {
128d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value);
129d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    return;
130d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
131d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
13234247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer  if (isUInt<16>(value)) {
133d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
134d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    return;
135d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
136d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
137d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen  if (isInt<16>(value)) {
138d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
139d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    return;
140d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
141d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
142d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  // We must split into halves
143d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  BuildMI(MBB, I, DL,
14473ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen          TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
145d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    .addImm((value >> 16) & 0xffff)
146d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    .addReg(Reg, RegState::ImplicitDefine);
147d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  BuildMI(MBB, I, DL,
14873ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen          TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
149d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    .addImm(value & 0xffff)
150d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    .addReg(Reg, RegState::ImplicitKill)
151d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    .addReg(Reg, RegState::ImplicitDefine);
152d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
153d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
154d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo::
155d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OleseneliminateCallFramePseudoInstr(MachineFunction &MF,
156d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                              MachineBasicBlock &MBB,
157d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                              MachineBasicBlock::iterator I) const {
15816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
159d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
160d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
161d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    int64_t Amount = I->getOperand(0).getImm();
162d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    if (Amount != 0) {
163ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen      assert(Amount%4 == 0 && "Unaligned call frame size");
164d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      if (I->getOpcode() == BF::ADJCALLSTACKDOWN) {
165d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount);
166d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      } else {
167ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen        assert(I->getOpcode() == BF::ADJCALLSTACKUP &&
168ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen               "Unknown call frame pseudo instruction");
169d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount);
170d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      }
171d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
172d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
173d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  MBB.erase(I);
174d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
175d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
176d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen/// findScratchRegister - Find a 'free' register. Try for a call-clobbered
177d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen/// register first and then a spilled callee-saved register if that fails.
178d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenstatic unsigned findScratchRegister(MachineBasicBlock::iterator II,
179d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                    RegScavenger *RS,
180d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                    const TargetRegisterClass *RC,
181d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                                    int SPAdj) {
182d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  assert(RS && "Register scavenging must be on");
183c0823fe7c679ca8f7d1667a310c2fca97b9402d5Jakob Stoklund Olesen  unsigned Reg = RS->FindUnusedReg(RC);
184d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  if (Reg == 0)
185d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    Reg = RS->scavengeRegister(RC, II, SPAdj);
186d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return Reg;
187d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
188d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
189fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
190b58f498f7502e7e1833decbbbb4df771367c7341Jim GrosbachBlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
191fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                          int SPAdj, RegScavenger *RS) const {
192d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  MachineInstr &MI = *II;
193d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  MachineBasicBlock &MBB = *MI.getParent();
194d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  MachineFunction &MF = *MBB.getParent();
19516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
196d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  DebugLoc DL = MI.getDebugLoc();
197d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
198ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen  unsigned FIPos;
199ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen  for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
200ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos < MI.getNumOperands() &&
201ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen           "Instr doesn't have FrameIndex operand!");
202d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
203ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen  int FrameIndex = MI.getOperand(FIPos).getIndex();
204ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen  assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm());
205d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex)
206ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    + MI.getOperand(FIPos+1).getImm();
207d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  unsigned BaseReg = BF::FP;
208d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF)) {
209ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer");
210d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  } else {
211d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BaseReg = BF::SP;
212d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    Offset += MF.getFrameInfo()->getStackSize() + SPAdj;
213d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
214d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
215d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  bool isStore = false;
216d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
217d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  switch (MI.getOpcode()) {
218d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::STORE32fi:
219d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    isStore = true;
220d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::LOAD32fi: {
221ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(Offset%4 == 0 && "Unaligned i32 stack access");
222ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos==1 && "Bad frame index operand");
223ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
224ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos+1).setImm(Offset);
22534247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    if (isUInt<6>(Offset)) {
226d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      MI.setDesc(TII.get(isStore
227d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         ? BF::STORE32p_uimm6m4
228d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         : BF::LOAD32p_uimm6m4));
229fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
230d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
23134247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    if (BaseReg == BF::FP && isUInt<7>(-Offset)) {
232d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      MI.setDesc(TII.get(isStore
233d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         ? BF::STORE32fp_nimm7m4
234d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         : BF::LOAD32fp_nimm7m4));
235ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen      MI.getOperand(FIPos+1).setImm(-Offset);
236fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
237d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
238d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen    if (isInt<18>(Offset)) {
239d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      MI.setDesc(TII.get(isStore
240d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         ? BF::STORE32p_imm18m4
241d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen                         : BF::LOAD32p_imm18m4));
242fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
243d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
244d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // Use RegScavenger to calculate proper offset...
245d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.dump();
246d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    llvm_unreachable("Stack frame offset too big");
247d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
248d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
249d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::ADDpp: {
250ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(MI.getOperand(0).isReg() && "ADD instruction needs a register");
251d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    unsigned DestReg = MI.getOperand(0).getReg();
252d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // We need to produce a stack offset in a P register. We emit:
253d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // P0 = offset;
254d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // P0 = BR + P0;
255ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos==1 && "Bad frame index operand");
256d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    loadConstant(MBB, II, DL, DestReg, Offset);
257d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.getOperand(1).ChangeToRegister(DestReg, false, false, true);
258d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.getOperand(2).ChangeToRegister(BaseReg, false);
259d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
260d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
261d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::STORE16fi:
262d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    isStore = true;
263d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::LOAD16fi: {
264ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(Offset%2 == 0 && "Unaligned i16 stack access");
265ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos==1 && "Bad frame index operand");
266d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // We need a P register to use as an address
267d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj);
268ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(ScratchReg && "Could not scavenge register");
269d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    loadConstant(MBB, II, DL, ScratchReg, Offset);
270d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg)
271d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(ScratchReg, RegState::Kill)
272d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      .addReg(BaseReg);
273d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi));
274d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true);
275d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.RemoveOperand(2);
276d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
277d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
278d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::STORE8fi: {
279d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // This is an AnyCC spill, we need a scratch register.
280ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos==1 && "Bad frame index operand");
281d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MachineOperand SpillReg = MI.getOperand(0);
282d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
283ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(ScratchReg && "Could not scavenge register");
284d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    if (SpillReg.getReg()==BF::NCC) {
285d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg)
286d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addOperand(SpillReg);
287d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg)
288d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addReg(ScratchReg).addImm(0);
289d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    } else {
290d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg)
291d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addOperand(SpillReg);
292d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
293d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // STORE D
294d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.setDesc(TII.get(BF::STORE8p_imm16));
295d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true);
296ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
297ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos+1).setImm(Offset);
298d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
299d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
300d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  case BF::LOAD8fi: {
301d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    // This is an restore, we need a scratch register.
302ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(FIPos==1 && "Bad frame index operand");
303d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MachineOperand SpillReg = MI.getOperand(0);
304d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
305ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    assert(ScratchReg && "Could not scavenge register");
306d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.setDesc(TII.get(BF::LOAD32p_imm16_8z));
307d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    MI.getOperand(0).ChangeToRegister(ScratchReg, true);
308ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
309ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen    MI.getOperand(FIPos+1).setImm(Offset);
310d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    ++II;
311d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    if (SpillReg.getReg()==BF::CC) {
312d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      // CC = D
313d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC)
314d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addReg(ScratchReg, RegState::Kill);
315d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    } else {
316d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      // Restore NCC (CC = D==0)
317d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen      BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC)
318d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addReg(ScratchReg, RegState::Kill)
319d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen        .addImm(0);
320d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    }
321d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
322d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
323d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  default:
324d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    llvm_unreachable("Cannot eliminate frame index");
325d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen    break;
326d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  }
327d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
328d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
3293f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned
3303f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneBlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
33116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
332d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
333d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF) ? BF::FP : BF::SP;
334d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
335d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
336d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenunsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
337d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  llvm_unreachable("What is the exception register");
338d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return 0;
339d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
340d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen
341d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenunsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
342d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  llvm_unreachable("What is the exception handler register");
343d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen  return 0;
344d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen}
345