1 //===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the MSP430 implementation of the TargetRegisterInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "MSP430RegisterInfo.h"
15 #include "MSP430MachineFunctionInfo.h"
16 #include "MSP430TargetMachine.h"
17 #include "llvm/ADT/BitVector.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetOptions.h"
28 #define DEBUG_TYPE "msp430-reg-info"
30 #define GET_REGINFO_TARGET_DESC
31 #include "MSP430GenRegisterInfo.inc"
33 // FIXME: Provide proper call frame setup / destroy opcodes.
34 MSP430RegisterInfo::MSP430RegisterInfo()
35 : MSP430GenRegisterInfo(MSP430::PC
) {}
38 MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
39 const MSP430FrameLowering
*TFI
= getFrameLowering(*MF
);
40 const Function
* F
= &MF
->getFunction();
41 static const MCPhysReg CalleeSavedRegs
[] = {
42 MSP430::R4
, MSP430::R5
, MSP430::R6
, MSP430::R7
,
43 MSP430::R8
, MSP430::R9
, MSP430::R10
,
46 static const MCPhysReg CalleeSavedRegsFP
[] = {
47 MSP430::R5
, MSP430::R6
, MSP430::R7
,
48 MSP430::R8
, MSP430::R9
, MSP430::R10
,
51 static const MCPhysReg CalleeSavedRegsIntr
[] = {
52 MSP430::R4
, MSP430::R5
, MSP430::R6
, MSP430::R7
,
53 MSP430::R8
, MSP430::R9
, MSP430::R10
, MSP430::R11
,
54 MSP430::R12
, MSP430::R13
, MSP430::R14
, MSP430::R15
,
57 static const MCPhysReg CalleeSavedRegsIntrFP
[] = {
58 MSP430::R5
, MSP430::R6
, MSP430::R7
,
59 MSP430::R8
, MSP430::R9
, MSP430::R10
, MSP430::R11
,
60 MSP430::R12
, MSP430::R13
, MSP430::R14
, MSP430::R15
,
65 return (F
->getCallingConv() == CallingConv::MSP430_INTR
?
66 CalleeSavedRegsIntrFP
: CalleeSavedRegsFP
);
68 return (F
->getCallingConv() == CallingConv::MSP430_INTR
?
69 CalleeSavedRegsIntr
: CalleeSavedRegs
);
73 BitVector
MSP430RegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
74 BitVector
Reserved(getNumRegs());
75 const MSP430FrameLowering
*TFI
= getFrameLowering(MF
);
77 // Mark 4 special registers with subregisters as reserved.
78 Reserved
.set(MSP430::PCB
);
79 Reserved
.set(MSP430::SPB
);
80 Reserved
.set(MSP430::SRB
);
81 Reserved
.set(MSP430::CGB
);
82 Reserved
.set(MSP430::PC
);
83 Reserved
.set(MSP430::SP
);
84 Reserved
.set(MSP430::SR
);
85 Reserved
.set(MSP430::CG
);
87 // Mark frame pointer as reserved if needed.
89 Reserved
.set(MSP430::R4B
);
90 Reserved
.set(MSP430::R4
);
96 const TargetRegisterClass
*
97 MSP430RegisterInfo::getPointerRegClass(const MachineFunction
&MF
, unsigned Kind
)
99 return &MSP430::GR16RegClass
;
103 MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
104 int SPAdj
, unsigned FIOperandNum
,
105 RegScavenger
*RS
) const {
106 assert(SPAdj
== 0 && "Unexpected");
108 MachineInstr
&MI
= *II
;
109 MachineBasicBlock
&MBB
= *MI
.getParent();
110 MachineFunction
&MF
= *MBB
.getParent();
111 const MSP430FrameLowering
*TFI
= getFrameLowering(MF
);
112 DebugLoc dl
= MI
.getDebugLoc();
113 int FrameIndex
= MI
.getOperand(FIOperandNum
).getIndex();
115 unsigned BasePtr
= (TFI
->hasFP(MF
) ? MSP430::R4
: MSP430::SP
);
116 int Offset
= MF
.getFrameInfo().getObjectOffset(FrameIndex
);
122 Offset
+= MF
.getFrameInfo().getStackSize();
124 Offset
+= 2; // Skip the saved FP
126 // Fold imm into offset
127 Offset
+= MI
.getOperand(FIOperandNum
+ 1).getImm();
129 if (MI
.getOpcode() == MSP430::ADDframe
) {
130 // This is actually "load effective address" of the stack slot
131 // instruction. We have only two-address instructions, thus we need to
132 // expand it into mov + add
133 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
135 MI
.setDesc(TII
.get(MSP430::MOV16rr
));
136 MI
.getOperand(FIOperandNum
).ChangeToRegister(BasePtr
, false);
138 // Remove the now unused Offset operand.
139 MI
.removeOperand(FIOperandNum
+ 1);
144 // We need to materialize the offset via add instruction.
145 Register DstReg
= MI
.getOperand(0).getReg();
147 BuildMI(MBB
, std::next(II
), dl
, TII
.get(MSP430::SUB16ri
), DstReg
)
148 .addReg(DstReg
).addImm(-Offset
);
150 BuildMI(MBB
, std::next(II
), dl
, TII
.get(MSP430::ADD16ri
), DstReg
)
151 .addReg(DstReg
).addImm(Offset
);
156 MI
.getOperand(FIOperandNum
).ChangeToRegister(BasePtr
, false);
157 MI
.getOperand(FIOperandNum
+ 1).ChangeToImmediate(Offset
);
161 Register
MSP430RegisterInfo::getFrameRegister(const MachineFunction
&MF
) const {
162 const MSP430FrameLowering
*TFI
= getFrameLowering(MF
);
163 return TFI
->hasFP(MF
) ? MSP430::R4
: MSP430::SP
;