1b22310fdSJia Liu //===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===//
210138001SAnton Korobeynikov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610138001SAnton Korobeynikov //
710138001SAnton Korobeynikov //===----------------------------------------------------------------------===//
810138001SAnton Korobeynikov //
910138001SAnton Korobeynikov // This file contains the MSP430 implementation of the TargetRegisterInfo class.
1010138001SAnton Korobeynikov //
1110138001SAnton Korobeynikov //===----------------------------------------------------------------------===//
1210138001SAnton Korobeynikov 
13b25fda95SCraig Topper #include "MSP430RegisterInfo.h"
1410138001SAnton Korobeynikov #include "MSP430.h"
15f2b50994SAnton Korobeynikov #include "MSP430MachineFunctionInfo.h"
16ec3f0b3fSAnton Korobeynikov #include "MSP430TargetMachine.h"
17ed0881b2SChandler Carruth #include "llvm/ADT/BitVector.h"
18efcd5aa3SAnton Korobeynikov #include "llvm/CodeGen/MachineFrameInfo.h"
1977e5a11eSAnton Korobeynikov #include "llvm/CodeGen/MachineFunction.h"
20ec3f0b3fSAnton Korobeynikov #include "llvm/CodeGen/MachineInstrBuilder.h"
219fb823bbSChandler Carruth #include "llvm/IR/Function.h"
22ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h"
2377e5a11eSAnton Korobeynikov #include "llvm/Target/TargetMachine.h"
24efcd5aa3SAnton Korobeynikov #include "llvm/Target/TargetOptions.h"
25d9997acdSEvan Cheng 
26d174b72aSChandler Carruth using namespace llvm;
27d174b72aSChandler Carruth 
2884e68b29SChandler Carruth #define DEBUG_TYPE "msp430-reg-info"
2984e68b29SChandler Carruth 
30d9997acdSEvan Cheng #define GET_REGINFO_TARGET_DESC
3124753317SEvan Cheng #include "MSP430GenRegisterInfo.inc"
3210138001SAnton Korobeynikov 
3310138001SAnton Korobeynikov // FIXME: Provide proper call frame setup / destroy opcodes.
MSP430RegisterInfo()3472a5b2a1SEric Christopher MSP430RegisterInfo::MSP430RegisterInfo()
35eb19aea4SJob Noorman   : MSP430GenRegisterInfo(MSP430::PC) {}
3610138001SAnton Korobeynikov 
37840beec2SCraig Topper const MCPhysReg*
getCalleeSavedRegs(const MachineFunction * MF) const3810138001SAnton Korobeynikov MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
39b73a2ed2SJF Bastien   const MSP430FrameLowering *TFI = getFrameLowering(*MF);
40f1caa283SMatthias Braun   const Function* F = &MF->getFunction();
41840beec2SCraig Topper   static const MCPhysReg CalleeSavedRegs[] = {
42*cb56fa21SAnatoly Trosinenko     MSP430::R4, MSP430::R5, MSP430::R6, MSP430::R7,
4338e30197SVadzim Dambrouski     MSP430::R8, MSP430::R9, MSP430::R10,
4469f51f0bSAnton Korobeynikov     0
4569f51f0bSAnton Korobeynikov   };
46840beec2SCraig Topper   static const MCPhysReg CalleeSavedRegsFP[] = {
47eb19aea4SJob Noorman     MSP430::R5, MSP430::R6, MSP430::R7,
4838e30197SVadzim Dambrouski     MSP430::R8, MSP430::R9, MSP430::R10,
493e9e87a9SAnton Korobeynikov     0
503e9e87a9SAnton Korobeynikov   };
51840beec2SCraig Topper   static const MCPhysReg CalleeSavedRegsIntr[] = {
52*cb56fa21SAnatoly Trosinenko     MSP430::R4,  MSP430::R5,  MSP430::R6,  MSP430::R7,
53eb19aea4SJob Noorman     MSP430::R8,  MSP430::R9,  MSP430::R10, MSP430::R11,
54eb19aea4SJob Noorman     MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
55b4be8ce5SAnton Korobeynikov     0
56b4be8ce5SAnton Korobeynikov   };
57840beec2SCraig Topper   static const MCPhysReg CalleeSavedRegsIntrFP[] = {
58eb19aea4SJob Noorman     MSP430::R5,  MSP430::R6,  MSP430::R7,
59eb19aea4SJob Noorman     MSP430::R8,  MSP430::R9,  MSP430::R10, MSP430::R11,
60eb19aea4SJob Noorman     MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15,
613e9e87a9SAnton Korobeynikov     0
623e9e87a9SAnton Korobeynikov   };
6369f51f0bSAnton Korobeynikov 
640eecf5d2SAnton Korobeynikov   if (TFI->hasFP(*MF))
653e9e87a9SAnton Korobeynikov     return (F->getCallingConv() == CallingConv::MSP430_INTR ?
663e9e87a9SAnton Korobeynikov             CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
673e9e87a9SAnton Korobeynikov   else
68b4be8ce5SAnton Korobeynikov     return (F->getCallingConv() == CallingConv::MSP430_INTR ?
69b4be8ce5SAnton Korobeynikov             CalleeSavedRegsIntr : CalleeSavedRegs);
703e9e87a9SAnton Korobeynikov 
7110138001SAnton Korobeynikov }
7210138001SAnton Korobeynikov 
getReservedRegs(const MachineFunction & MF) const73ee68a483SChris Lattner BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
74c10f98acSAnton Korobeynikov   BitVector Reserved(getNumRegs());
75b73a2ed2SJF Bastien   const MSP430FrameLowering *TFI = getFrameLowering(MF);
76c10f98acSAnton Korobeynikov 
775750ca70SJakob Stoklund Olesen   // Mark 4 special registers with subregisters as reserved.
785750ca70SJakob Stoklund Olesen   Reserved.set(MSP430::PCB);
795750ca70SJakob Stoklund Olesen   Reserved.set(MSP430::SPB);
805750ca70SJakob Stoklund Olesen   Reserved.set(MSP430::SRB);
815750ca70SJakob Stoklund Olesen   Reserved.set(MSP430::CGB);
82eb19aea4SJob Noorman   Reserved.set(MSP430::PC);
83eb19aea4SJob Noorman   Reserved.set(MSP430::SP);
84eb19aea4SJob Noorman   Reserved.set(MSP430::SR);
85eb19aea4SJob Noorman   Reserved.set(MSP430::CG);
86c10f98acSAnton Korobeynikov 
87c10f98acSAnton Korobeynikov   // Mark frame pointer as reserved if needed.
88f7da105fSJob Noorman   if (TFI->hasFP(MF)) {
89*cb56fa21SAnatoly Trosinenko     Reserved.set(MSP430::R4B);
90*cb56fa21SAnatoly Trosinenko     Reserved.set(MSP430::R4);
91f7da105fSJob Noorman   }
92c10f98acSAnton Korobeynikov 
93c10f98acSAnton Korobeynikov   return Reserved;
9410138001SAnton Korobeynikov }
9510138001SAnton Korobeynikov 
96ee68a483SChris Lattner const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const973c52f028SJakob Stoklund Olesen MSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
983c52f028SJakob Stoklund Olesen                                                                          const {
99f6af822cSAnton Korobeynikov   return &MSP430::GR16RegClass;
100f6af822cSAnton Korobeynikov }
101f6af822cSAnton Korobeynikov 
1026a770669SJim Grosbach void
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const10310138001SAnton Korobeynikov MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
104df782d22SChad Rosier                                         int SPAdj, unsigned FIOperandNum,
105df782d22SChad Rosier                                         RegScavenger *RS) const {
106f6af822cSAnton Korobeynikov   assert(SPAdj == 0 && "Unexpected");
107f6af822cSAnton Korobeynikov 
108f6af822cSAnton Korobeynikov   MachineInstr &MI = *II;
1097784ae9aSAnton Korobeynikov   MachineBasicBlock &MBB = *MI.getParent();
1107784ae9aSAnton Korobeynikov   MachineFunction &MF = *MBB.getParent();
111b73a2ed2SJF Bastien   const MSP430FrameLowering *TFI = getFrameLowering(MF);
1127784ae9aSAnton Korobeynikov   DebugLoc dl = MI.getDebugLoc();
113df782d22SChad Rosier   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
114f6af822cSAnton Korobeynikov 
115*cb56fa21SAnatoly Trosinenko   unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::R4 : MSP430::SP);
116941a705bSMatthias Braun   int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
117f6af822cSAnton Korobeynikov 
118f6af822cSAnton Korobeynikov   // Skip the saved PC
119f6af822cSAnton Korobeynikov   Offset += 2;
120f6af822cSAnton Korobeynikov 
1210eecf5d2SAnton Korobeynikov   if (!TFI->hasFP(MF))
122941a705bSMatthias Braun     Offset += MF.getFrameInfo().getStackSize();
123f2b50994SAnton Korobeynikov   else
124eb19aea4SJob Noorman     Offset += 2; // Skip the saved FP
125f2b50994SAnton Korobeynikov 
126f6af822cSAnton Korobeynikov   // Fold imm into offset
127df782d22SChad Rosier   Offset += MI.getOperand(FIOperandNum + 1).getImm();
1287784ae9aSAnton Korobeynikov 
129b07351f4SVadzim Dambrouski   if (MI.getOpcode() == MSP430::ADDframe) {
1307784ae9aSAnton Korobeynikov     // This is actually "load effective address" of the stack slot
1317784ae9aSAnton Korobeynikov     // instruction. We have only two-address instructions, thus we need to
1327784ae9aSAnton Korobeynikov     // expand it into mov + add
133fc6de428SEric Christopher     const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
1347784ae9aSAnton Korobeynikov 
1357784ae9aSAnton Korobeynikov     MI.setDesc(TII.get(MSP430::MOV16rr));
136df782d22SChad Rosier     MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
1377784ae9aSAnton Korobeynikov 
1387784ae9aSAnton Korobeynikov     if (Offset == 0)
1396a770669SJim Grosbach       return;
1407784ae9aSAnton Korobeynikov 
1417784ae9aSAnton Korobeynikov     // We need to materialize the offset via add instruction.
1420c476111SDaniel Sanders     Register DstReg = MI.getOperand(0).getReg();
1437784ae9aSAnton Korobeynikov     if (Offset < 0)
144b6d0bd48SBenjamin Kramer       BuildMI(MBB, std::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
1457784ae9aSAnton Korobeynikov         .addReg(DstReg).addImm(-Offset);
1467784ae9aSAnton Korobeynikov     else
147b6d0bd48SBenjamin Kramer       BuildMI(MBB, std::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
1487784ae9aSAnton Korobeynikov         .addReg(DstReg).addImm(Offset);
1497784ae9aSAnton Korobeynikov 
1506a770669SJim Grosbach     return;
1517784ae9aSAnton Korobeynikov   }
1527784ae9aSAnton Korobeynikov 
153df782d22SChad Rosier   MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
154df782d22SChad Rosier   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
15510138001SAnton Korobeynikov }
15610138001SAnton Korobeynikov 
getFrameRegister(const MachineFunction & MF) const157e3a676e9SMatt Arsenault Register MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
158b73a2ed2SJF Bastien   const MSP430FrameLowering *TFI = getFrameLowering(MF);
159*cb56fa21SAnatoly Trosinenko   return TFI->hasFP(MF) ? MSP430::R4 : MSP430::SP;
16010138001SAnton Korobeynikov }
161