MSP430RegisterInfo.cpp revision b561264d2b2e33e1e6322a99d600b5daece5bbde
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===- 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 14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-reg-info" 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h" 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430RegisterInfo.h" 18b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h" 193a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 202dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 21b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 222dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h" 233a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.h" 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/BitVector.h" 25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes. 29b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikovMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm, 30b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov const TargetInstrInfo &tii) 31b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov : MSP430GenRegisterInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP), 32b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov TM(tm), TII(tii) { 33b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov StackAlign = TM.getFrameInfo()->getStackAlignment(); 34b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov} 35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 36f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst unsigned* 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 38fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov static const unsigned CalleeSavedRegs[] = { 39cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W, 40cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 41fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 0 42fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov }; 43fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 44fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov return CalleeSavedRegs; 45f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 46f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 47f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst TargetRegisterClass* const* 48f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 49fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 501df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov &MSP430::GR16RegClass, &MSP430::GR16RegClass, 511df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov &MSP430::GR16RegClass, &MSP430::GR16RegClass, 521df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov &MSP430::GR16RegClass, &MSP430::GR16RegClass, 531df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov &MSP430::GR16RegClass, &MSP430::GR16RegClass, 54fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 0 55fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov }; 56fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 57fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov return CalleeSavedRegClasses; 58f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 59f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 60f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovBitVector 61f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 62dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov BitVector Reserved(getNumRegs()); 63dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 64dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Mark 4 special registers as reserved. 65cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::PCW); 66cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::SPW); 67cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::SRW); 68cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::CGW); 69dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 70dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Mark frame pointer as reserved if needed. 71dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov if (hasFP(MF)) 72cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::FPW); 73dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 74dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov return Reserved; 75f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 76f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 77f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovbool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const { 783a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); 79f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 80f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 81b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovbool MSP430RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 82b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 83b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov} 84b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 85b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovvoid MSP430RegisterInfo:: 86b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 87b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineBasicBlock::iterator I) const { 88b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (!hasReservedCallFrame(MF)) { 89b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // If the stack pointer can be changed after prologue, turn the 90b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // adjcallstackup instruction into a 'sub SPW, <amt>' and the 91b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // adjcallstackdown instruction into 'add SPW, <amt>' 92b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // TODO: consider using push / pop instead of sub + store / add 93b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *Old = I; 94b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov uint64_t Amount = Old->getOperand(0).getImm(); 95b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (Amount != 0) { 96b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // We need to keep the stack aligned properly. To do this, we round the 97b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // amount of space needed for the outgoing arguments up to the next 98b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // alignment boundary. 99b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 100b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 101b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *New = 0; 102b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (Old->getOpcode() == getCallFrameSetupOpcode()) { 103b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New = BuildMI(MF, Old->getDebugLoc(), 104b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov TII.get(MSP430::SUB16ri), MSP430::SPW) 105b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov .addReg(MSP430::SPW).addImm(Amount); 106b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } else { 107b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov assert(Old->getOpcode() == getCallFrameDestroyOpcode()); 108b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // factor out the amount the callee already popped. 109b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov uint64_t CalleeAmt = Old->getOperand(1).getImm(); 110b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov Amount -= CalleeAmt; 111b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (Amount) 112b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New = BuildMI(MF, Old->getDebugLoc(), 113b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov TII.get(MSP430::ADD16ri), MSP430::SPW) 114b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov .addReg(MSP430::SPW).addImm(Amount); 115b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 116b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 117b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (New) { 118b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // The SRW implicit def is dead. 119b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New->getOperand(3).setIsDead(); 120b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 121b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // Replace the pseudo instruction with a new instruction... 122b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.insert(I, New); 123b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 124b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 125b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } else if (I->getOpcode() == getCallFrameDestroyOpcode()) { 126b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // If we are performing frame pointer elimination and if the callee pops 127b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // something off the stack pointer, add it back. 128b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 129b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *Old = I; 130b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *New = 131b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 132b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 133b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // The SRW implicit def is dead. 134b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New->getOperand(3).setIsDead(); 135b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 136b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.insert(I, New); 137b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 138b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 139b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 140b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.erase(I); 141b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov} 142b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 143f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid 144f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 145f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov int SPAdj, RegScavenger *RS) const { 146f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov assert(0 && "Not implemented yet!"); 147f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 148f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 149f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const { 150e37db97928a63008a096e6151f7a68fe2de35694Anton Korobeynikov // Nothing here yet 151f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 152f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 153f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovvoid MSP430RegisterInfo::emitEpilogue(MachineFunction &MF, 154f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov MachineBasicBlock &MBB) const { 155e37db97928a63008a096e6151f7a68fe2de35694Anton Korobeynikov // Nothing here yet 156f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 157f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 158f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovunsigned MSP430RegisterInfo::getRARegister() const { 159f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov assert(0 && "Not implemented yet!"); 160f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 161f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 162f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovunsigned MSP430RegisterInfo::getFrameRegister(MachineFunction &MF) const { 163f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov assert(0 && "Not implemented yet!"); 164f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 165f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 166f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovint MSP430RegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 167f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov assert(0 && "Not implemented yet!"); 168f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 169f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 170f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenRegisterInfo.inc" 171