131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- 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
1679aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "MSP430RegisterInfo.h"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
18ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov#include "MSP430MachineFunctionInfo.h"
19b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/BitVector.h"
213a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
222dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
23b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
262dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h"
273a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.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
41015f228861ef9b337366f92f637d4e8d624bb006Craig Topperconst uint16_t*
42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
4316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering();
44e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  const Function* F = MF->getFunction();
45015f228861ef9b337366f92f637d4e8d624bb006Craig Topper  static const uint16_t 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  };
50015f228861ef9b337366f92f637d4e8d624bb006Craig Topper  static const uint16_t CalleeSavedRegsFP[] = {
517058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R5W, MSP430::R6W, MSP430::R7W,
527058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
537058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
547058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
55015f228861ef9b337366f92f637d4e8d624bb006Craig Topper  static const uint16_t 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  };
61015f228861ef9b337366f92f637d4e8d624bb006Craig Topper  static const uint16_t 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 *
99397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund OlesenMSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
100397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen                                                                         const {
101aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  return &MSP430::GR16RegClass;
102aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
103aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
104fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
105f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
106108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        int SPAdj, unsigned FIOperandNum,
107108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        RegScavenger *RS) const {
108aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  assert(SPAdj == 0 && "Unexpected");
109aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
110aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MachineInstr &MI = *II;
11140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineBasicBlock &MBB = *MI.getParent();
11240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
11316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
11440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  DebugLoc dl = MI.getDebugLoc();
115108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
116aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
117d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW);
118aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
119aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
120aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Skip the saved PC
121aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += 2;
122aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
123d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasFP(MF))
124ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += MF.getFrameInfo()->getStackSize();
125ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  else
126ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += 2; // Skip the saved FPW
127ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
128aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Fold imm into offset
129108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  Offset += MI.getOperand(FIOperandNum + 1).getImm();
13040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
13140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  if (MI.getOpcode() == MSP430::ADD16ri) {
13240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // This is actually "load effective address" of the stack slot
13340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // instruction. We have only two-address instructions, thus we need to
13440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // expand it into mov + add
13540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
13640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    MI.setDesc(TII.get(MSP430::MOV16rr));
137108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier    MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
13840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
13940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset == 0)
140fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach      return;
14140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
14240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // We need to materialize the offset via add instruction.
14340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    unsigned DstReg = MI.getOperand(0).getReg();
14440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    if (Offset < 0)
1457896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
14640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(-Offset);
14740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    else
1487896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
14940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(Offset);
15040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
151fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
15240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  }
15340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
154108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
155108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
156f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
157f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
1583f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
15916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
160d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
161d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW;
162f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
163