1234353Sdim//===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the MSP430 implementation of the TargetRegisterInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#define DEBUG_TYPE "msp430-reg-info"
15193323Sed
16234353Sdim#include "MSP430RegisterInfo.h"
17193323Sed#include "MSP430.h"
18193323Sed#include "MSP430MachineFunctionInfo.h"
19193323Sed#include "MSP430TargetMachine.h"
20249423Sdim#include "llvm/ADT/BitVector.h"
21193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
22193323Sed#include "llvm/CodeGen/MachineFunction.h"
23193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
24249423Sdim#include "llvm/IR/Function.h"
25249423Sdim#include "llvm/Support/ErrorHandling.h"
26193323Sed#include "llvm/Target/TargetMachine.h"
27193323Sed#include "llvm/Target/TargetOptions.h"
28193323Sed
29224145Sdim#define GET_REGINFO_TARGET_DESC
30224145Sdim#include "MSP430GenRegisterInfo.inc"
31224145Sdim
32193323Sedusing namespace llvm;
33193323Sed
34193323Sed// FIXME: Provide proper call frame setup / destroy opcodes.
35263508SdimMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm)
36263508Sdim  : MSP430GenRegisterInfo(MSP430::PCW), TM(tm) {
37218893Sdim  StackAlign = TM.getFrameLowering()->getStackAlignment();
38193323Sed}
39193323Sed
40234353Sdimconst uint16_t*
41193323SedMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
42218893Sdim  const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering();
43200581Srdivacky  const Function* F = MF->getFunction();
44234353Sdim  static const uint16_t CalleeSavedRegs[] = {
45193323Sed    MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
46193323Sed    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
47193323Sed    0
48193323Sed  };
49234353Sdim  static const uint16_t CalleeSavedRegsFP[] = {
50201360Srdivacky    MSP430::R5W, MSP430::R6W, MSP430::R7W,
51201360Srdivacky    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
52201360Srdivacky    0
53201360Srdivacky  };
54234353Sdim  static const uint16_t CalleeSavedRegsIntr[] = {
55200581Srdivacky    MSP430::FPW,  MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
56200581Srdivacky    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
57200581Srdivacky    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
58200581Srdivacky    0
59200581Srdivacky  };
60234353Sdim  static const uint16_t CalleeSavedRegsIntrFP[] = {
61201360Srdivacky    MSP430::R5W,  MSP430::R6W,  MSP430::R7W,
62201360Srdivacky    MSP430::R8W,  MSP430::R9W,  MSP430::R10W, MSP430::R11W,
63201360Srdivacky    MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
64201360Srdivacky    0
65201360Srdivacky  };
66193323Sed
67218893Sdim  if (TFI->hasFP(*MF))
68201360Srdivacky    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
69201360Srdivacky            CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
70201360Srdivacky  else
71201360Srdivacky    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
72201360Srdivacky            CalleeSavedRegsIntr : CalleeSavedRegs);
73201360Srdivacky
74193323Sed}
75193323Sed
76198090SrdivackyBitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
77193323Sed  BitVector Reserved(getNumRegs());
78218893Sdim  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
79193323Sed
80223017Sdim  // Mark 4 special registers with subregisters as reserved.
81223017Sdim  Reserved.set(MSP430::PCB);
82223017Sdim  Reserved.set(MSP430::SPB);
83223017Sdim  Reserved.set(MSP430::SRB);
84223017Sdim  Reserved.set(MSP430::CGB);
85193323Sed  Reserved.set(MSP430::PCW);
86193323Sed  Reserved.set(MSP430::SPW);
87193323Sed  Reserved.set(MSP430::SRW);
88193323Sed  Reserved.set(MSP430::CGW);
89193323Sed
90193323Sed  // Mark frame pointer as reserved if needed.
91218893Sdim  if (TFI->hasFP(MF))
92193323Sed    Reserved.set(MSP430::FPW);
93193323Sed
94193323Sed  return Reserved;
95193323Sed}
96193323Sed
97198090Srdivackyconst TargetRegisterClass *
98239462SdimMSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
99239462Sdim                                                                         const {
100193323Sed  return &MSP430::GR16RegClass;
101193323Sed}
102193323Sed
103212904Sdimvoid
104193323SedMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
105249423Sdim                                        int SPAdj, unsigned FIOperandNum,
106249423Sdim                                        RegScavenger *RS) const {
107193323Sed  assert(SPAdj == 0 && "Unexpected");
108193323Sed
109193323Sed  MachineInstr &MI = *II;
110193323Sed  MachineBasicBlock &MBB = *MI.getParent();
111193323Sed  MachineFunction &MF = *MBB.getParent();
112218893Sdim  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
113193323Sed  DebugLoc dl = MI.getDebugLoc();
114249423Sdim  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
115193323Sed
116218893Sdim  unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW);
117193323Sed  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
118193323Sed
119193323Sed  // Skip the saved PC
120193323Sed  Offset += 2;
121193323Sed
122218893Sdim  if (!TFI->hasFP(MF))
123193323Sed    Offset += MF.getFrameInfo()->getStackSize();
124193323Sed  else
125193323Sed    Offset += 2; // Skip the saved FPW
126193323Sed
127193323Sed  // Fold imm into offset
128249423Sdim  Offset += MI.getOperand(FIOperandNum + 1).getImm();
129193323Sed
130193323Sed  if (MI.getOpcode() == MSP430::ADD16ri) {
131193323Sed    // This is actually "load effective address" of the stack slot
132193323Sed    // instruction. We have only two-address instructions, thus we need to
133193323Sed    // expand it into mov + add
134263508Sdim    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
135193323Sed
136193323Sed    MI.setDesc(TII.get(MSP430::MOV16rr));
137249423Sdim    MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
138193323Sed
139193323Sed    if (Offset == 0)
140212904Sdim      return;
141193323Sed
142193323Sed    // We need to materialize the offset via add instruction.
143193323Sed    unsigned DstReg = MI.getOperand(0).getReg();
144193323Sed    if (Offset < 0)
145200581Srdivacky      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
146193323Sed        .addReg(DstReg).addImm(-Offset);
147193323Sed    else
148200581Srdivacky      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
149193323Sed        .addReg(DstReg).addImm(Offset);
150193323Sed
151212904Sdim    return;
152193323Sed  }
153193323Sed
154249423Sdim  MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
155249423Sdim  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
156193323Sed}
157193323Sed
158199481Srdivackyunsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
159218893Sdim  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
160218893Sdim
161218893Sdim  return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW;
162193323Sed}
163