10b57cec5SDimitry Andric //===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the MSP430 implementation of the TargetRegisterInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MSP430RegisterInfo.h" 140b57cec5SDimitry Andric #include "MSP430.h" 150b57cec5SDimitry Andric #include "MSP430MachineFunctionInfo.h" 160b57cec5SDimitry Andric #include "MSP430TargetMachine.h" 170b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 210b57cec5SDimitry Andric #include "llvm/IR/Function.h" 220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 230b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 240b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace llvm; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric #define DEBUG_TYPE "msp430-reg-info" 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #define GET_REGINFO_TARGET_DESC 310b57cec5SDimitry Andric #include "MSP430GenRegisterInfo.inc" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric // FIXME: Provide proper call frame setup / destroy opcodes. 340b57cec5SDimitry Andric MSP430RegisterInfo::MSP430RegisterInfo() 350b57cec5SDimitry Andric : MSP430GenRegisterInfo(MSP430::PC) {} 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric const MCPhysReg* 380b57cec5SDimitry Andric MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 390b57cec5SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(*MF); 400b57cec5SDimitry Andric const Function* F = &MF->getFunction(); 410b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegs[] = { 425ffd83dbSDimitry Andric MSP430::R4, MSP430::R5, MSP430::R6, MSP430::R7, 430b57cec5SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, 440b57cec5SDimitry Andric 0 450b57cec5SDimitry Andric }; 460b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegsFP[] = { 470b57cec5SDimitry Andric MSP430::R5, MSP430::R6, MSP430::R7, 480b57cec5SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, 490b57cec5SDimitry Andric 0 500b57cec5SDimitry Andric }; 510b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegsIntr[] = { 525ffd83dbSDimitry Andric MSP430::R4, MSP430::R5, MSP430::R6, MSP430::R7, 530b57cec5SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11, 540b57cec5SDimitry Andric MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15, 550b57cec5SDimitry Andric 0 560b57cec5SDimitry Andric }; 570b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegsIntrFP[] = { 580b57cec5SDimitry Andric MSP430::R5, MSP430::R6, MSP430::R7, 590b57cec5SDimitry Andric MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11, 600b57cec5SDimitry Andric MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15, 610b57cec5SDimitry Andric 0 620b57cec5SDimitry Andric }; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric if (TFI->hasFP(*MF)) 650b57cec5SDimitry Andric return (F->getCallingConv() == CallingConv::MSP430_INTR ? 660b57cec5SDimitry Andric CalleeSavedRegsIntrFP : CalleeSavedRegsFP); 670b57cec5SDimitry Andric else 680b57cec5SDimitry Andric return (F->getCallingConv() == CallingConv::MSP430_INTR ? 690b57cec5SDimitry Andric CalleeSavedRegsIntr : CalleeSavedRegs); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 740b57cec5SDimitry Andric BitVector Reserved(getNumRegs()); 750b57cec5SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Mark 4 special registers with subregisters as reserved. 780b57cec5SDimitry Andric Reserved.set(MSP430::PCB); 790b57cec5SDimitry Andric Reserved.set(MSP430::SPB); 800b57cec5SDimitry Andric Reserved.set(MSP430::SRB); 810b57cec5SDimitry Andric Reserved.set(MSP430::CGB); 820b57cec5SDimitry Andric Reserved.set(MSP430::PC); 830b57cec5SDimitry Andric Reserved.set(MSP430::SP); 840b57cec5SDimitry Andric Reserved.set(MSP430::SR); 850b57cec5SDimitry Andric Reserved.set(MSP430::CG); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // Mark frame pointer as reserved if needed. 880b57cec5SDimitry Andric if (TFI->hasFP(MF)) { 895ffd83dbSDimitry Andric Reserved.set(MSP430::R4B); 905ffd83dbSDimitry Andric Reserved.set(MSP430::R4); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric return Reserved; 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric const TargetRegisterClass * 970b57cec5SDimitry Andric MSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) 980b57cec5SDimitry Andric const { 990b57cec5SDimitry Andric return &MSP430::GR16RegClass; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 102*bdd1243dSDimitry Andric bool 1030b57cec5SDimitry Andric MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 1040b57cec5SDimitry Andric int SPAdj, unsigned FIOperandNum, 1050b57cec5SDimitry Andric RegScavenger *RS) const { 1060b57cec5SDimitry Andric assert(SPAdj == 0 && "Unexpected"); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric MachineInstr &MI = *II; 1090b57cec5SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 1100b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 1110b57cec5SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF); 1120b57cec5SDimitry Andric DebugLoc dl = MI.getDebugLoc(); 1130b57cec5SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 1140b57cec5SDimitry Andric 1155ffd83dbSDimitry Andric unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::R4 : MSP430::SP); 1160b57cec5SDimitry Andric int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // Skip the saved PC 1190b57cec5SDimitry Andric Offset += 2; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric if (!TFI->hasFP(MF)) 1220b57cec5SDimitry Andric Offset += MF.getFrameInfo().getStackSize(); 1230b57cec5SDimitry Andric else 1240b57cec5SDimitry Andric Offset += 2; // Skip the saved FP 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric // Fold imm into offset 1270b57cec5SDimitry Andric Offset += MI.getOperand(FIOperandNum + 1).getImm(); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric if (MI.getOpcode() == MSP430::ADDframe) { 1300b57cec5SDimitry Andric // This is actually "load effective address" of the stack slot 1310b57cec5SDimitry Andric // instruction. We have only two-address instructions, thus we need to 1320b57cec5SDimitry Andric // expand it into mov + add 1330b57cec5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric MI.setDesc(TII.get(MSP430::MOV16rr)); 1360b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric if (Offset == 0) 139*bdd1243dSDimitry Andric return false; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric // We need to materialize the offset via add instruction. 1428bcb0991SDimitry Andric Register DstReg = MI.getOperand(0).getReg(); 1430b57cec5SDimitry Andric if (Offset < 0) 1440b57cec5SDimitry Andric BuildMI(MBB, std::next(II), dl, TII.get(MSP430::SUB16ri), DstReg) 1450b57cec5SDimitry Andric .addReg(DstReg).addImm(-Offset); 1460b57cec5SDimitry Andric else 1470b57cec5SDimitry Andric BuildMI(MBB, std::next(II), dl, TII.get(MSP430::ADD16ri), DstReg) 1480b57cec5SDimitry Andric .addReg(DstReg).addImm(Offset); 1490b57cec5SDimitry Andric 150*bdd1243dSDimitry Andric return false; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 1540b57cec5SDimitry Andric MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 155*bdd1243dSDimitry Andric return false; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric Register MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 1590b57cec5SDimitry Andric const MSP430FrameLowering *TFI = getFrameLowering(MF); 1605ffd83dbSDimitry Andric return TFI->hasFP(MF) ? MSP430::R4 : MSP430::SP; 1610b57cec5SDimitry Andric } 162