MSP430RegisterInfo.cpp revision b561264d2b2e33e1e6322a99d600b5daece5bbde
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"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430RegisterInfo.h"
18b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h"
193a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
202dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
21b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
222dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h"
233a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/BitVector.h"
25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes.
29b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikovMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
30b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                                       const TargetInstrInfo &tii)
31b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  : MSP430GenRegisterInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
32b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    TM(tm), TII(tii) {
33b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  StackAlign = TM.getFrameInfo()->getStackAlignment();
34b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
36f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst unsigned*
37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
38fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  static const unsigned CalleeSavedRegs[] = {
39cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
40cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
41fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov    0
42fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  };
43fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov
44fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  return CalleeSavedRegs;
45f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
46f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
47f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst TargetRegisterClass* const*
48f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
49fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
501df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov    &MSP430::GR16RegClass, &MSP430::GR16RegClass,
511df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov    &MSP430::GR16RegClass, &MSP430::GR16RegClass,
521df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov    &MSP430::GR16RegClass, &MSP430::GR16RegClass,
531df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov    &MSP430::GR16RegClass, &MSP430::GR16RegClass,
54fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov    0
55fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  };
56fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov
57fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  return CalleeSavedRegClasses;
58f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
59f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
60f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovBitVector
61f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
62dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  BitVector Reserved(getNumRegs());
63dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
64dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Mark 4 special registers as reserved.
65cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::PCW);
66cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SPW);
67cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::SRW);
68cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov  Reserved.set(MSP430::CGW);
69dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
70dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Mark frame pointer as reserved if needed.
71dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  if (hasFP(MF))
72cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov    Reserved.set(MSP430::FPW);
73dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
74dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  return Reserved;
75f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
76f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
77f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovbool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const {
783a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov  return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
79f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
80f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
81b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovbool MSP430RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
82b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  return !MF.getFrameInfo()->hasVarSizedObjects();
83b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
84b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
85b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovvoid MSP430RegisterInfo::
86b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
87b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                              MachineBasicBlock::iterator I) const {
88b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  if (!hasReservedCallFrame(MF)) {
89b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If the stack pointer can be changed after prologue, turn the
90b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackup instruction into a 'sub SPW, <amt>' and the
91b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // adjcallstackdown instruction into 'add SPW, <amt>'
92b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // TODO: consider using push / pop instead of sub + store / add
93b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    MachineInstr *Old = I;
94b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    uint64_t Amount = Old->getOperand(0).getImm();
95b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (Amount != 0) {
96b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // We need to keep the stack aligned properly.  To do this, we round the
97b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // amount of space needed for the outgoing arguments up to the next
98b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // alignment boundary.
99b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
100b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
101b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New = 0;
102b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      if (Old->getOpcode() == getCallFrameSetupOpcode()) {
103b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New = BuildMI(MF, Old->getDebugLoc(),
104b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                      TII.get(MSP430::SUB16ri), MSP430::SPW)
105b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          .addReg(MSP430::SPW).addImm(Amount);
106b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      } else {
107b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        assert(Old->getOpcode() == getCallFrameDestroyOpcode());
108b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // factor out the amount the callee already popped.
109b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        uint64_t CalleeAmt = Old->getOperand(1).getImm();
110b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        Amount -= CalleeAmt;
111b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        if (Amount)
112b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov          New = BuildMI(MF, Old->getDebugLoc(),
113b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                        TII.get(MSP430::ADD16ri), MSP430::SPW)
114b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov            .addReg(MSP430::SPW).addImm(Amount);
115b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
116b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
117b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      if (New) {
118b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // The SRW implicit def is dead.
119b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        New->getOperand(3).setIsDead();
120b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
121b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        // Replace the pseudo instruction with a new instruction...
122b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        MBB.insert(I, New);
123b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      }
124b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
125b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  } else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
126b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // If we are performing frame pointer elimination and if the callee pops
127b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    // something off the stack pointer, add it back.
128b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
129b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *Old = I;
130b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MachineInstr *New =
131b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov        BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
132b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov                MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
133b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      // The SRW implicit def is dead.
134b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      New->getOperand(3).setIsDead();
135b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
136b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov      MBB.insert(I, New);
137b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov    }
138b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  }
139b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
140b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  MBB.erase(I);
141b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov}
142b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov
143f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid
144f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
145f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov                                        int SPAdj, RegScavenger *RS) const {
146f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  assert(0 && "Not implemented yet!");
147f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
148f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
149f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const {
150e37db97928a63008a096e6151f7a68fe2de35694Anton Korobeynikov  // Nothing here yet
151f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
152f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
153f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid MSP430RegisterInfo::emitEpilogue(MachineFunction &MF,
154f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov                                      MachineBasicBlock &MBB) const {
155e37db97928a63008a096e6151f7a68fe2de35694Anton Korobeynikov  // Nothing here yet
156f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
157f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
158f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovunsigned MSP430RegisterInfo::getRARegister() const {
159f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  assert(0 && "Not implemented yet!");
160f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
161f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
162f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovunsigned MSP430RegisterInfo::getFrameRegister(MachineFunction &MF) const {
163f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  assert(0 && "Not implemented yet!");
164f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
165f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
166f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovint MSP430RegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
167f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  assert(0 && "Not implemented yet!");
168f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
169f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
170f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenRegisterInfo.inc"
171