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" 17ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov#include "MSP430MachineFunctionInfo.h" 18f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430RegisterInfo.h" 19b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "MSP430TargetMachine.h" 20e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov#include "llvm/Function.h" 213a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 222dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 23b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 242dd6cdc9204eaca42923509d227ef67974784aaeAnton Korobeynikov#include "llvm/Target/TargetMachine.h" 253a4fbcfd330de43011550079f811d92f741a08a1Anton Korobeynikov#include "llvm/Target/TargetOptions.h" 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/BitVector.h" 27c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 2873f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng 2973f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC 30a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "MSP430GenRegisterInfo.inc" 31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// FIXME: Provide proper call frame setup / destroy opcodes. 35b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikovMSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm, 36b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov const TargetInstrInfo &tii) 370e6a052331f674dd70e28af41f654a7874405eabEvan Cheng : MSP430GenRegisterInfo(MSP430::PCW), TM(tm), TII(tii) { 3816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov StackAlign = TM.getFrameLowering()->getStackAlignment(); 39b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov} 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst unsigned* 42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 4316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering(); 44e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov const Function* F = MF->getFunction(); 45fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov static const unsigned CalleeSavedRegs[] = { 46cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W, 47cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 48fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 0 49fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov }; 507058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov static const unsigned CalleeSavedRegsFP[] = { 517058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov MSP430::R5W, MSP430::R6W, MSP430::R7W, 527058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 537058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov 0 547058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov }; 55e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov static const unsigned CalleeSavedRegsIntr[] = { 56e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W, 57e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 58e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W, 59e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 0 60e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov }; 617058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov static const unsigned CalleeSavedRegsIntrFP[] = { 627058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov MSP430::R5W, MSP430::R6W, MSP430::R7W, 637058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 647058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W, 657058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov 0 667058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov }; 677058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov 68d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(*MF)) 697058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov return (F->getCallingConv() == CallingConv::MSP430_INTR ? 707058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov CalleeSavedRegsIntrFP : CalleeSavedRegsFP); 717058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov else 727058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov return (F->getCallingConv() == CallingConv::MSP430_INTR ? 737058f9c114cbfcaa3276948806f108a6d362eda7Anton Korobeynikov CalleeSavedRegsIntr : CalleeSavedRegs); 74fbf165a74b33e2a3b36cf45f22f1bae89558373bAnton Korobeynikov 75f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 76f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 772cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerBitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 78dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov BitVector Reserved(getNumRegs()); 7916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 80dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 812a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen // Mark 4 special registers with subregisters as reserved. 822a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen Reserved.set(MSP430::PCB); 832a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen Reserved.set(MSP430::SPB); 842a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen Reserved.set(MSP430::SRB); 852a9d1ca9c244aeac98044a5fc9a081ff3df7b2ffJakob Stoklund Olesen Reserved.set(MSP430::CGB); 86cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::PCW); 87cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::SPW); 88cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::SRW); 89cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::CGW); 90dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 91dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Mark frame pointer as reserved if needed. 92d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) 93cf9adf2cbb8298e83b53d7bee2ddab4c875cb3c5Anton Korobeynikov Reserved.set(MSP430::FPW); 94dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 95dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov return Reserved; 96f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 97f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 982cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass * 992cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerMSP430RegisterInfo::getPointerRegClass(unsigned Kind) const { 100aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov return &MSP430::GR16RegClass; 101aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov} 102aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 103b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovvoid MSP430RegisterInfo:: 104b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton KorobeynikoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 105b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineBasicBlock::iterator I) const { 10616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 107d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 108d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasReservedCallFrame(MF)) { 109b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // If the stack pointer can be changed after prologue, turn the 110b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // adjcallstackup instruction into a 'sub SPW, <amt>' and the 111b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // adjcallstackdown instruction into 'add SPW, <amt>' 112b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // TODO: consider using push / pop instead of sub + store / add 113b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *Old = I; 114b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov uint64_t Amount = Old->getOperand(0).getImm(); 115b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (Amount != 0) { 116b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // We need to keep the stack aligned properly. To do this, we round the 117b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // amount of space needed for the outgoing arguments up to the next 118b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // alignment boundary. 119b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 120b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 121b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *New = 0; 122d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 123b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New = BuildMI(MF, Old->getDebugLoc(), 124b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov TII.get(MSP430::SUB16ri), MSP430::SPW) 125b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov .addReg(MSP430::SPW).addImm(Amount); 126b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } else { 127d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 128b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // factor out the amount the callee already popped. 129b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov uint64_t CalleeAmt = Old->getOperand(1).getImm(); 130b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov Amount -= CalleeAmt; 131b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (Amount) 132b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New = BuildMI(MF, Old->getDebugLoc(), 133b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov TII.get(MSP430::ADD16ri), MSP430::SPW) 134b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov .addReg(MSP430::SPW).addImm(Amount); 135b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 136b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 137b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (New) { 138b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // The SRW implicit def is dead. 139b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New->getOperand(3).setIsDead(); 140b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 141b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // Replace the pseudo instruction with a new instruction... 142b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.insert(I, New); 143b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 144b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 145d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 146b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // If we are performing frame pointer elimination and if the callee pops 147b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // something off the stack pointer, add it back. 148b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 149b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *Old = I; 150b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MachineInstr *New = 151b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 152b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 153b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov // The SRW implicit def is dead. 154b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov New->getOperand(3).setIsDead(); 155b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 156b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.insert(I, New); 157b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 158b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov } 159b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 160b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov MBB.erase(I); 161b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov} 162b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov 163fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid 164f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 165fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach int SPAdj, RegScavenger *RS) const { 166aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov assert(SPAdj == 0 && "Unexpected"); 167aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 168aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov unsigned i = 0; 169aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov MachineInstr &MI = *II; 17040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov MachineBasicBlock &MBB = *MI.getParent(); 17140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov MachineFunction &MF = *MBB.getParent(); 17216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 17340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov DebugLoc dl = MI.getDebugLoc(); 174aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov while (!MI.getOperand(i).isFI()) { 175aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov ++i; 176aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 177aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov } 178aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 179aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov int FrameIndex = MI.getOperand(i).getIndex(); 180aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 181d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW); 182aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 183aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 184aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov // Skip the saved PC 185aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov Offset += 2; 186aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov 187d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasFP(MF)) 188ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov Offset += MF.getFrameInfo()->getStackSize(); 189ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov else 190ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov Offset += 2; // Skip the saved FPW 191ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov 192aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov // Fold imm into offset 193aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov Offset += MI.getOperand(i+1).getImm(); 19440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 19540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov if (MI.getOpcode() == MSP430::ADD16ri) { 19640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov // This is actually "load effective address" of the stack slot 19740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov // instruction. We have only two-address instructions, thus we need to 19840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov // expand it into mov + add 19940477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 20040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov MI.setDesc(TII.get(MSP430::MOV16rr)); 20140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov MI.getOperand(i).ChangeToRegister(BasePtr, false); 20240477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 20340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov if (Offset == 0) 204fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 20540477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 20640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov // We need to materialize the offset via add instruction. 20740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov unsigned DstReg = MI.getOperand(0).getReg(); 20840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov if (Offset < 0) 2097896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg) 21040477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov .addReg(DstReg).addImm(-Offset); 21140477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov else 2127896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg) 21340477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov .addReg(DstReg).addImm(Offset); 21440477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 215fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 21640477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov } 21740477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov 21840477317f39dccfd5c9c139feabda1becc6bd49cAnton Korobeynikov MI.getOperand(i).ChangeToRegister(BasePtr, false); 219aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov MI.getOperand(i+1).ChangeToImmediate(Offset); 220f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 221f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 222ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikovvoid 223ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton KorobeynikovMSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) 224ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov const { 22516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 226d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 227ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov // Create a frame entry for the FPW register that must be saved. 228d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) { 229c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 230c5080ba0c8278fba57efe605560d1f16a7a9e973Chandler Carruth (void)FrameIdx; 231ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 232ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov "Slot for FPW register must be last in order to be found!"); 233ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov } 234ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov} 235ce45d30fa1922d19745f7307cf1bb712c5814b9aAnton Korobeynikov 2363f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 23716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 238d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 239d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW; 240f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 241