1dff0c46cSDimitry Andric //===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file contains the MSP430 implementation of the TargetRegisterInfo class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14dff0c46cSDimitry Andric #include "MSP430RegisterInfo.h"
15f22ef01cSRoman Divacky #include "MSP430.h"
16f22ef01cSRoman Divacky #include "MSP430MachineFunctionInfo.h"
17f22ef01cSRoman Divacky #include "MSP430TargetMachine.h"
18139f7f9bSDimitry Andric #include "llvm/ADT/BitVector.h"
19f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
20f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
21f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstrBuilder.h"
22139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
23139f7f9bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
24f22ef01cSRoman Divacky #include "llvm/Target/TargetMachine.h"
25f22ef01cSRoman Divacky #include "llvm/Target/TargetOptions.h"
26f22ef01cSRoman Divacky
2791bc56edSDimitry Andric using namespace llvm;
2891bc56edSDimitry Andric
2991bc56edSDimitry Andric #define DEBUG_TYPE "msp430-reg-info"
3091bc56edSDimitry Andric
3117a519f9SDimitry Andric #define GET_REGINFO_TARGET_DESC
3217a519f9SDimitry Andric #include "MSP430GenRegisterInfo.inc"
3317a519f9SDimitry Andric
34f22ef01cSRoman Divacky // FIXME: Provide proper call frame setup / destroy opcodes.
MSP430RegisterInfo()3591bc56edSDimitry Andric MSP430RegisterInfo::MSP430RegisterInfo()
3639d628a0SDimitry Andric : MSP430GenRegisterInfo(MSP430::PC) {}
37f22ef01cSRoman Divacky
3891bc56edSDimitry Andric const MCPhysReg*
getCalleeSavedRegs(const MachineFunction * MF) const39f22ef01cSRoman Divacky MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
40875ed548SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(*MF);
41*2cab237bSDimitry Andric const Function* F = &MF->getFunction();
4291bc56edSDimitry Andric static const MCPhysReg CalleeSavedRegs[] = {
4339d628a0SDimitry Andric MSP430::FP, MSP430::R5, MSP430::R6, MSP430::R7,
445517e702SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10,
45f22ef01cSRoman Divacky 0
46f22ef01cSRoman Divacky };
4791bc56edSDimitry Andric static const MCPhysReg CalleeSavedRegsFP[] = {
4839d628a0SDimitry Andric MSP430::R5, MSP430::R6, MSP430::R7,
495517e702SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10,
50f22ef01cSRoman Divacky 0
51f22ef01cSRoman Divacky };
5291bc56edSDimitry Andric static const MCPhysReg CalleeSavedRegsIntr[] = {
5339d628a0SDimitry Andric MSP430::FP, MSP430::R5, MSP430::R6, MSP430::R7,
5439d628a0SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
5539d628a0SDimitry Andric MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
56f22ef01cSRoman Divacky 0
57f22ef01cSRoman Divacky };
5891bc56edSDimitry Andric static const MCPhysReg CalleeSavedRegsIntrFP[] = {
5939d628a0SDimitry Andric MSP430::R5, MSP430::R6, MSP430::R7,
6039d628a0SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
6139d628a0SDimitry Andric MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
62f22ef01cSRoman Divacky 0
63f22ef01cSRoman Divacky };
64f22ef01cSRoman Divacky
652754fe60SDimitry Andric if (TFI->hasFP(*MF))
66f22ef01cSRoman Divacky return (F->getCallingConv() == CallingConv::MSP430_INTR ?
67f22ef01cSRoman Divacky CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
68f22ef01cSRoman Divacky else
69f22ef01cSRoman Divacky return (F->getCallingConv() == CallingConv::MSP430_INTR ?
70f22ef01cSRoman Divacky CalleeSavedRegsIntr : CalleeSavedRegs);
71f22ef01cSRoman Divacky
72f22ef01cSRoman Divacky }
73f22ef01cSRoman Divacky
getReservedRegs(const MachineFunction & MF) const74f22ef01cSRoman Divacky BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
75f22ef01cSRoman Divacky BitVector Reserved(getNumRegs());
76875ed548SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF);
77f22ef01cSRoman Divacky
78bd5abe19SDimitry Andric // Mark 4 special registers with subregisters as reserved.
79bd5abe19SDimitry Andric Reserved.set(MSP430::PCB);
80bd5abe19SDimitry Andric Reserved.set(MSP430::SPB);
81bd5abe19SDimitry Andric Reserved.set(MSP430::SRB);
82bd5abe19SDimitry Andric Reserved.set(MSP430::CGB);
8339d628a0SDimitry Andric Reserved.set(MSP430::PC);
8439d628a0SDimitry Andric Reserved.set(MSP430::SP);
8539d628a0SDimitry Andric Reserved.set(MSP430::SR);
8639d628a0SDimitry Andric Reserved.set(MSP430::CG);
87f22ef01cSRoman Divacky
88f22ef01cSRoman Divacky // Mark frame pointer as reserved if needed.
8991bc56edSDimitry Andric if (TFI->hasFP(MF)) {
9091bc56edSDimitry Andric Reserved.set(MSP430::FPB);
9139d628a0SDimitry Andric Reserved.set(MSP430::FP);
9291bc56edSDimitry Andric }
93f22ef01cSRoman Divacky
94f22ef01cSRoman Divacky return Reserved;
95f22ef01cSRoman Divacky }
96f22ef01cSRoman Divacky
97f22ef01cSRoman Divacky const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const987ae0e2c9SDimitry Andric MSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
997ae0e2c9SDimitry Andric const {
100f22ef01cSRoman Divacky return &MSP430::GR16RegClass;
101f22ef01cSRoman Divacky }
102f22ef01cSRoman Divacky
103e580952dSDimitry Andric void
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const104f22ef01cSRoman Divacky MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
105139f7f9bSDimitry Andric int SPAdj, unsigned FIOperandNum,
106139f7f9bSDimitry Andric RegScavenger *RS) const {
107f22ef01cSRoman Divacky assert(SPAdj == 0 && "Unexpected");
108f22ef01cSRoman Divacky
109f22ef01cSRoman Divacky MachineInstr &MI = *II;
110f22ef01cSRoman Divacky MachineBasicBlock &MBB = *MI.getParent();
111f22ef01cSRoman Divacky MachineFunction &MF = *MBB.getParent();
112875ed548SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF);
113f22ef01cSRoman Divacky DebugLoc dl = MI.getDebugLoc();
114139f7f9bSDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
115f22ef01cSRoman Divacky
11639d628a0SDimitry Andric unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FP : MSP430::SP);
117d88c1a5aSDimitry Andric int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
118f22ef01cSRoman Divacky
119f22ef01cSRoman Divacky // Skip the saved PC
120f22ef01cSRoman Divacky Offset += 2;
121f22ef01cSRoman Divacky
1222754fe60SDimitry Andric if (!TFI->hasFP(MF))
123d88c1a5aSDimitry Andric Offset += MF.getFrameInfo().getStackSize();
124f22ef01cSRoman Divacky else
12539d628a0SDimitry Andric Offset += 2; // Skip the saved FP
126f22ef01cSRoman Divacky
127f22ef01cSRoman Divacky // Fold imm into offset
128139f7f9bSDimitry Andric Offset += MI.getOperand(FIOperandNum + 1).getImm();
129f22ef01cSRoman Divacky
130302affcbSDimitry Andric if (MI.getOpcode() == MSP430::ADDframe) {
131f22ef01cSRoman Divacky // This is actually "load effective address" of the stack slot
132f22ef01cSRoman Divacky // instruction. We have only two-address instructions, thus we need to
133f22ef01cSRoman Divacky // expand it into mov + add
13439d628a0SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
135f22ef01cSRoman Divacky
136f22ef01cSRoman Divacky MI.setDesc(TII.get(MSP430::MOV16rr));
137139f7f9bSDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
138f22ef01cSRoman Divacky
139f22ef01cSRoman Divacky if (Offset == 0)
140e580952dSDimitry Andric return;
141f22ef01cSRoman Divacky
142f22ef01cSRoman Divacky // We need to materialize the offset via add instruction.
143f22ef01cSRoman Divacky unsigned DstReg = MI.getOperand(0).getReg();
144f22ef01cSRoman Divacky if (Offset < 0)
14591bc56edSDimitry Andric BuildMI(MBB, std::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
146f22ef01cSRoman Divacky .addReg(DstReg).addImm(-Offset);
147f22ef01cSRoman Divacky else
14891bc56edSDimitry Andric BuildMI(MBB, std::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
149f22ef01cSRoman Divacky .addReg(DstReg).addImm(Offset);
150f22ef01cSRoman Divacky
151e580952dSDimitry Andric return;
152f22ef01cSRoman Divacky }
153f22ef01cSRoman Divacky
154139f7f9bSDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
155139f7f9bSDimitry Andric MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
156f22ef01cSRoman Divacky }
157f22ef01cSRoman Divacky
getFrameRegister(const MachineFunction & MF) const158f22ef01cSRoman Divacky unsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
159875ed548SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF);
16039d628a0SDimitry Andric return TFI->hasFP(MF) ? MSP430::FP : MSP430::SP;
161f22ef01cSRoman Divacky }
162