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
1479aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "MSP430RegisterInfo.h"
15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
16ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov#include "MSP430MachineFunctionInfo.h"
17b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/BitVector.h"
193a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
202dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
21b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
242dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h"
253a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.h"
2673f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm;
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "msp430-reg-info"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3173f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC
32a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "MSP430GenRegisterInfo.inc"
33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes.
35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMSP430RegisterInfo::MSP430RegisterInfo()
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  : MSP430GenRegisterInfo(MSP430::PC) {}
37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst MCPhysReg*
39f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
41e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  const Function* F = MF->getFunction();
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg CalleeSavedRegs[] = {
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::FP, MSP430::R5, MSP430::R6, MSP430::R7,
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
45fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov    0
46fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov  };
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg CalleeSavedRegsFP[] = {
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R5, MSP430::R6, MSP430::R7,
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
507058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
517058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg CalleeSavedRegsIntr[] = {
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::FP,  MSP430::R5,  MSP430::R6,  MSP430::R7,
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R8,  MSP430::R9,  MSP430::R10, MSP430::R11,
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
56e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    0
57e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  };
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg CalleeSavedRegsIntrFP[] = {
5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R5,  MSP430::R6,  MSP430::R7,
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R8,  MSP430::R9,  MSP430::R10, MSP430::R11,
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
627058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    0
637058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  };
647058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov
65d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(*MF))
667058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
677058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
687058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov  else
697058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov    return (F->getCallingConv() == CallingConv::MSP430_INTR ?
707058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov            CalleeSavedRegsIntr : CalleeSavedRegs);
71fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov
72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
742cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerBitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
75dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  BitVector Reserved(getNumRegs());
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
77dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
782a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  // Mark 4 special registers with subregisters as reserved.
792a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::PCB);
802a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SPB);
812a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::SRB);
822a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen  Reserved.set(MSP430::CGB);
8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Reserved.set(MSP430::PC);
8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Reserved.set(MSP430::SP);
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Reserved.set(MSP430::SR);
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Reserved.set(MSP430::CG);
87dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
88dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Mark frame pointer as reserved if needed.
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (TFI->hasFP(MF)) {
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Reserved.set(MSP430::FPB);
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Reserved.set(MSP430::FP);
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
93dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
94dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  return Reserved;
95f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
96f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
972cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass *
98397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund OlesenMSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
99397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen                                                                         const {
100aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  return &MSP430::GR16RegClass;
101aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
102aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
103fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
104f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
105108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        int SPAdj, unsigned FIOperandNum,
106108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        RegScavenger *RS) const {
107aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  assert(SPAdj == 0 && "Unexpected");
108aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
109aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  MachineInstr &MI = *II;
11040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineBasicBlock &MBB = *MI.getParent();
11140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
11340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  DebugLoc dl = MI.getDebugLoc();
114108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
115aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FP : MSP430::SP);
117aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
118aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
119aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Skip the saved PC
120aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  Offset += 2;
121aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
122d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasFP(MF))
123ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov    Offset += MF.getFrameInfo()->getStackSize();
124ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov  else
12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Offset += 2; // Skip the saved FP
126ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov
127aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  // Fold imm into offset
128108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  Offset += MI.getOperand(FIOperandNum + 1).getImm();
12940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov
13040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov  if (MI.getOpcode() == MSP430::ADD16ri) {
13140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // This is actually "load effective address" of the stack slot
13240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // instruction. We have only two-address instructions, thus we need to
13340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    // expand it into mov + add
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
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)
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(MBB, std::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
14640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov        .addReg(DstReg).addImm(-Offset);
14740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov    else
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(MBB, std::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 {
15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
160d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return TFI->hasFP(MF) ? MSP430::FP : MSP430::SP;
162f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
163