MSP430RegisterInfo.cpp revision 73f50d9bc3bd46cc0abeba9bb0d46977ba1aea42
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===- MSP430RegisterInfo.cpp - MSP430 Register Information ---------------===//
2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//                     The LLVM Compiler Infrastructure
4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details.
7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file contains the MSP430 implementation of the TargetRegisterInfo class.
11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-reg-info"
15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
17ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov#include "MSP430MachineFunctionInfo.h"
18f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430RegisterInfo.h"
19b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h"
20e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov#include "llvm/Function.h"
213a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
222dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
23b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
242dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h"
253a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.h"
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/BitVector.h"
27c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
2873f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
2973f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_MC_DESC
3073f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC
31a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "MSP430GenRegisterInfo.inc"
32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes.
36b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikovMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
37b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                                       const TargetInstrInfo &tii)
38a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng  : MSP430GenRegisterInfo(MSP430RegDesc, MSP430RegInfoDesc,
39a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng                          MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
40b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    TM(tm), TII(tii) {
4116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  StackAlign = TM.getFrameLowering()->getStackAlignment();
42b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
43f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
44f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst unsigned*
45f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
4616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering();
47e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  const Function* F = MF->getFunction();
48fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  static const unsigned CalleeSavedRegs[] = {
49cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
50cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
51fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov    0
52fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  };
537058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  static const unsigned CalleeSavedRegsFP[] = {
547058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R5W, MSP430::R6W, MSP430::R7W,
557058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
567058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
577058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
58e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  static const unsigned CalleeSavedRegsIntr[] = {
59e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::FPW,  MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
60e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
61e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
62e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    0
63e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  };
647058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  static const unsigned CalleeSavedRegsIntrFP[] = {
657058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
667058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
677058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
687058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
697058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
707058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov
71d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(*MF))
727058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
737058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
747058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  else
757058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
767058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntr : CalleeSavedRegs);
77fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov
78f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
79f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
802cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerBitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
81dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  BitVector Reserved(getNumRegs());
8216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
83dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
842a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  // Mark 4 special registers with subregisters as reserved.
852a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::PCB);
862a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SPB);
872a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SRB);
882a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::CGB);
89cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::PCW);
90cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SPW);
91cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SRW);
92cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::CGW);
93dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
94dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Mark frame pointer as reserved if needed.
95d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
96cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    Reserved.set(MSP430::FPW);
97dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
98dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  return Reserved;
99f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
100f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
1012cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass *
1022cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerMSP430RegisterInfo::getPointerRegClass(unsigned Kind) const {
103aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  return &MSP430::GR16RegClass;
104aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
105aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
106b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovvoid MSP430RegisterInfo::
107b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
108b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                              MachineBasicBlock::iterator I) const {
10916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
110d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
111d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
112b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If the stack pointer can be changed after prologue, turn the
113b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackup instruction into a 'sub SPW, <amt>' and the
114b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackdown instruction into 'add SPW, <amt>'
115b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // TODO: consider using push / pop instead of sub + store / add
116b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    MachineInstr *Old = I;
117b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    uint64_t Amount = Old->getOperand(0).getImm();
118b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (Amount != 0) {
119b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // We need to keep the stack aligned properly.  To do this, we round the
120b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // amount of space needed for the outgoing arguments up to the next
121b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // alignment boundary.
122b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
123b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
124b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New = 0;
125b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      if (Old->getOpcode() == getCallFrameSetupOpcode()) {
126b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New = BuildMI(MF, Old->getDebugLoc(),
127b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                      TII.get(MSP430::SUB16ri), MSP430::SPW)
128b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          .addReg(MSP430::SPW).addImm(Amount);
129b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      } else {
130b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        assert(Old->getOpcode() == getCallFrameDestroyOpcode());
131b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // factor out the amount the callee already popped.
132b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        uint64_t CalleeAmt = Old->getOperand(1).getImm();
133b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        Amount -= CalleeAmt;
134b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        if (Amount)
135b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          New = BuildMI(MF, Old->getDebugLoc(),
136b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                        TII.get(MSP430::ADD16ri), MSP430::SPW)
137b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov            .addReg(MSP430::SPW).addImm(Amount);
138b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
139b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
140b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      if (New) {
141b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // The SRW implicit def is dead.
142b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New->getOperand(3).setIsDead();
143b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
144b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // Replace the pseudo instruction with a new instruction...
145b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        MBB.insert(I, New);
146b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
147b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
148b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  } else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
149b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If we are performing frame pointer elimination and if the callee pops
150b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // something off the stack pointer, add it back.
151b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
152b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *Old = I;
153b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New =
154b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
155b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
156b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // The SRW implicit def is dead.
157b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      New->getOperand(3).setIsDead();
158b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
159b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MBB.insert(I, New);
160b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
161b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  }
162b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
163b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  MBB.erase(I);
164b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
165b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
166fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
167f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
168fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                        int SPAdj, RegScavenger *RS) const {
169aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  assert(SPAdj == 0 && "Unexpected");
170aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
171aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  unsigned i = 0;
172aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MachineInstr &MI = *II;
17340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineBasicBlock &MBB = *MI.getParent();
17440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
17516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
17640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  DebugLoc dl = MI.getDebugLoc();
177aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  while (!MI.getOperand(i).isFI()) {
178aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    ++i;
179aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
180aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  }
181aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
182aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int FrameIndex = MI.getOperand(i).getIndex();
183aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
184d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW);
185aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
186aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
187aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Skip the saved PC
188aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += 2;
189aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
190d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasFP(MF))
191ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += MF.getFrameInfo()->getStackSize();
192ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  else
193ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += 2; // Skip the saved FPW
194ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
195aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Fold imm into offset
196aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += MI.getOperand(i+1).getImm();
19740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
19840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  if (MI.getOpcode() == MSP430::ADD16ri) {
19940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // This is actually "load effective address" of the stack slot
20040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // instruction. We have only two-address instructions, thus we need to
20140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // expand it into mov + add
20240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    MI.setDesc(TII.get(MSP430::MOV16rr));
20440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    MI.getOperand(i).ChangeToRegister(BasePtr, false);
20540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset == 0)
207fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
20840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // We need to materialize the offset via add instruction.
21040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    unsigned DstReg = MI.getOperand(0).getReg();
21140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset < 0)
2127896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
21340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(-Offset);
21440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    else
2157896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
21640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(Offset);
21740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
218fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
21940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  }
22040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
22140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MI.getOperand(i).ChangeToRegister(BasePtr, false);
222aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MI.getOperand(i+1).ChangeToImmediate(Offset);
223f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
224f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
225ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikovvoid
226ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton KorobeynikovMSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
227ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov                                                                         const {
22816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
229d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
230ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  // Create a frame entry for the FPW register that must be saved.
231d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF)) {
232c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth    int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
233c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth    (void)FrameIdx;
234ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
235ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov           "Slot for FPW register must be last in order to be found!");
236ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  }
237ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov}
238ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
239f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovunsigned MSP430RegisterInfo::getRARegister() const {
240875e1eb8ab7c6210f3d6d55d358e2c6a751f2cbbAnton Korobeynikov  return MSP430::PCW;
241f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
242f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
2433f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
24416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
245d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
246d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW;
247f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
248f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
249f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovint MSP430RegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
250c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("Not implemented yet!");
25110ac96b276fbd5208494a1d5b3c215d7eaa62a9fDuncan Sands  return 0;
252f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
253f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
2546e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindolaint MSP430RegisterInfo::getLLVMRegNum(unsigned RegNum, bool isEH) const {
2556e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola  llvm_unreachable("Not implemented yet!");
2566e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola  return 0;
2576e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola}
258