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_TARGET_DESC
30a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "MSP430GenRegisterInfo.inc"
31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes.
35b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikovMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
36b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                                       const TargetInstrInfo &tii)
370e6a052331f674dd70e28af41f654a7874405eabEvan Cheng  : MSP430GenRegisterInfo(MSP430::PCW), TM(tm), TII(tii) {
3816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  StackAlign = TM.getFrameLowering()->getStackAlignment();
39b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst unsigned*
42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
4316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering();
44e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  const Function* F = MF->getFunction();
45fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  static const unsigned CalleeSavedRegs[] = {
46cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
47cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
48fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov    0
49fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  };
507058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  static const unsigned CalleeSavedRegsFP[] = {
517058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R5W, MSP430::R6W, MSP430::R7W,
527058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
537058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
547058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
55e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  static const unsigned CalleeSavedRegsIntr[] = {
56e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::FPW,  MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
57e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
58e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
59e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    0
60e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  };
617058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  static const unsigned CalleeSavedRegsIntrFP[] = {
627058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
637058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
647058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
657058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
667058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
677058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov
68d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(*MF))
697058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
707058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
717058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  else
727058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
737058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntr : CalleeSavedRegs);
74fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov
75f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
76f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
772cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerBitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
78dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  BitVector Reserved(getNumRegs());
7916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
80dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
812a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  // Mark 4 special registers with subregisters as reserved.
822a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::PCB);
832a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SPB);
842a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SRB);
852a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::CGB);
86cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::PCW);
87cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SPW);
88cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SRW);
89cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::CGW);
90dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
91dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Mark frame pointer as reserved if needed.
92d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
93cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    Reserved.set(MSP430::FPW);
94dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
95dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  return Reserved;
96f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
97f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
982cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass *
992cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerMSP430RegisterInfo::getPointerRegClass(unsigned Kind) const {
100aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  return &MSP430::GR16RegClass;
101aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
102aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
103b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovvoid MSP430RegisterInfo::
104b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
105b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                              MachineBasicBlock::iterator I) const {
10616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
107d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
108d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
109b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If the stack pointer can be changed after prologue, turn the
110b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackup instruction into a 'sub SPW, <amt>' and the
111b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackdown instruction into 'add SPW, <amt>'
112b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // TODO: consider using push / pop instead of sub + store / add
113b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    MachineInstr *Old = I;
114b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    uint64_t Amount = Old->getOperand(0).getImm();
115b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (Amount != 0) {
116b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // We need to keep the stack aligned properly.  To do this, we round the
117b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // amount of space needed for the outgoing arguments up to the next
118b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // alignment boundary.
119b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
120b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
121b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New = 0;
122d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng      if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
123b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New = BuildMI(MF, Old->getDebugLoc(),
124b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                      TII.get(MSP430::SUB16ri), MSP430::SPW)
125b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          .addReg(MSP430::SPW).addImm(Amount);
126b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      } else {
127d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng        assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
128b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // factor out the amount the callee already popped.
129b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        uint64_t CalleeAmt = Old->getOperand(1).getImm();
130b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        Amount -= CalleeAmt;
131b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        if (Amount)
132b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          New = BuildMI(MF, Old->getDebugLoc(),
133b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                        TII.get(MSP430::ADD16ri), MSP430::SPW)
134b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov            .addReg(MSP430::SPW).addImm(Amount);
135b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
136b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
137b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      if (New) {
138b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // The SRW implicit def is dead.
139b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New->getOperand(3).setIsDead();
140b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
141b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // Replace the pseudo instruction with a new instruction...
142b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        MBB.insert(I, New);
143b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
144b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
145d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
146b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If we are performing frame pointer elimination and if the callee pops
147b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // something off the stack pointer, add it back.
148b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
149b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *Old = I;
150b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New =
151b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
152b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
153b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // The SRW implicit def is dead.
154b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      New->getOperand(3).setIsDead();
155b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
156b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MBB.insert(I, New);
157b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
158b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  }
159b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
160b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  MBB.erase(I);
161b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
162b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
163fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
164f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
165fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                        int SPAdj, RegScavenger *RS) const {
166aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  assert(SPAdj == 0 && "Unexpected");
167aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
168aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  unsigned i = 0;
169aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MachineInstr &MI = *II;
17040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineBasicBlock &MBB = *MI.getParent();
17140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
17216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
17340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  DebugLoc dl = MI.getDebugLoc();
174aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  while (!MI.getOperand(i).isFI()) {
175aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    ++i;
176aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
177aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  }
178aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
179aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int FrameIndex = MI.getOperand(i).getIndex();
180aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
181d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW);
182aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
183aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
184aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Skip the saved PC
185aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += 2;
186aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
187d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasFP(MF))
188ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += MF.getFrameInfo()->getStackSize();
189ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  else
190ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += 2; // Skip the saved FPW
191ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
192aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Fold imm into offset
193aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += MI.getOperand(i+1).getImm();
19440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
19540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  if (MI.getOpcode() == MSP430::ADD16ri) {
19640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // This is actually "load effective address" of the stack slot
19740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // instruction. We have only two-address instructions, thus we need to
19840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // expand it into mov + add
19940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    MI.setDesc(TII.get(MSP430::MOV16rr));
20140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    MI.getOperand(i).ChangeToRegister(BasePtr, false);
20240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset == 0)
204fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
20540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
20640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // We need to materialize the offset via add instruction.
20740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    unsigned DstReg = MI.getOperand(0).getReg();
20840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset < 0)
2097896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
21040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(-Offset);
21140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    else
2127896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
21340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(Offset);
21440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
215fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
21640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  }
21740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
21840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MI.getOperand(i).ChangeToRegister(BasePtr, false);
219aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MI.getOperand(i+1).ChangeToImmediate(Offset);
220f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
221f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
222ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikovvoid
223ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton KorobeynikovMSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
224ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov                                                                         const {
22516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
226d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
227ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  // Create a frame entry for the FPW register that must be saved.
228d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF)) {
229c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth    int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
230c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth    (void)FrameIdx;
231ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
232ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov           "Slot for FPW register must be last in order to be found!");
233ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  }
234ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov}
235ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
2363f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
23716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
238d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
239d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW;
240f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
241