1 //===- MSP430RegisterInfo.cpp - MSP430 Register Information ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the MSP430 implementation of the TargetRegisterInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "msp430-reg-info" 15 16 #include "MSP430.h" 17 #include "MSP430MachineFunctionInfo.h" 18 #include "MSP430RegisterInfo.h" 19 #include "MSP430TargetMachine.h" 20 #include "llvm/Function.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/Target/TargetMachine.h" 25 #include "llvm/Target/TargetOptions.h" 26 #include "llvm/ADT/BitVector.h" 27 #include "llvm/Support/ErrorHandling.h" 28 29 #define GET_REGINFO_TARGET_DESC 30 #include "MSP430GenRegisterInfo.inc" 31 32 using namespace llvm; 33 34 // FIXME: Provide proper call frame setup / destroy opcodes. 35 MSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm, 36 const TargetInstrInfo &tii) 37 : MSP430GenRegisterInfo(MSP430::PCW), TM(tm), TII(tii) { 38 StackAlign = TM.getFrameLowering()->getStackAlignment(); 39 } 40 41 const unsigned* 42 MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 43 const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering(); 44 const Function* F = MF->getFunction(); 45 static const unsigned CalleeSavedRegs[] = { 46 MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W, 47 MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 48 0 49 }; 50 static const unsigned CalleeSavedRegsFP[] = { 51 MSP430::R5W, MSP430::R6W, MSP430::R7W, 52 MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 53 0 54 }; 55 static const unsigned CalleeSavedRegsIntr[] = { 56 MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W, 57 MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 58 MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W, 59 0 60 }; 61 static const unsigned CalleeSavedRegsIntrFP[] = { 62 MSP430::R5W, MSP430::R6W, MSP430::R7W, 63 MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W, 64 MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W, 65 0 66 }; 67 68 if (TFI->hasFP(*MF)) 69 return (F->getCallingConv() == CallingConv::MSP430_INTR ? 70 CalleeSavedRegsIntrFP : CalleeSavedRegsFP); 71 else 72 return (F->getCallingConv() == CallingConv::MSP430_INTR ? 73 CalleeSavedRegsIntr : CalleeSavedRegs); 74 75 } 76 77 BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 78 BitVector Reserved(getNumRegs()); 79 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 80 81 // Mark 4 special registers with subregisters as reserved. 82 Reserved.set(MSP430::PCB); 83 Reserved.set(MSP430::SPB); 84 Reserved.set(MSP430::SRB); 85 Reserved.set(MSP430::CGB); 86 Reserved.set(MSP430::PCW); 87 Reserved.set(MSP430::SPW); 88 Reserved.set(MSP430::SRW); 89 Reserved.set(MSP430::CGW); 90 91 // Mark frame pointer as reserved if needed. 92 if (TFI->hasFP(MF)) 93 Reserved.set(MSP430::FPW); 94 95 return Reserved; 96 } 97 98 const TargetRegisterClass * 99 MSP430RegisterInfo::getPointerRegClass(unsigned Kind) const { 100 return &MSP430::GR16RegClass; 101 } 102 103 void MSP430RegisterInfo:: 104 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 105 MachineBasicBlock::iterator I) const { 106 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 107 108 if (!TFI->hasReservedCallFrame(MF)) { 109 // If the stack pointer can be changed after prologue, turn the 110 // adjcallstackup instruction into a 'sub SPW, <amt>' and the 111 // adjcallstackdown instruction into 'add SPW, <amt>' 112 // TODO: consider using push / pop instead of sub + store / add 113 MachineInstr *Old = I; 114 uint64_t Amount = Old->getOperand(0).getImm(); 115 if (Amount != 0) { 116 // We need to keep the stack aligned properly. To do this, we round the 117 // amount of space needed for the outgoing arguments up to the next 118 // alignment boundary. 119 Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 120 121 MachineInstr *New = 0; 122 if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 123 New = BuildMI(MF, Old->getDebugLoc(), 124 TII.get(MSP430::SUB16ri), MSP430::SPW) 125 .addReg(MSP430::SPW).addImm(Amount); 126 } else { 127 assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 128 // factor out the amount the callee already popped. 129 uint64_t CalleeAmt = Old->getOperand(1).getImm(); 130 Amount -= CalleeAmt; 131 if (Amount) 132 New = BuildMI(MF, Old->getDebugLoc(), 133 TII.get(MSP430::ADD16ri), MSP430::SPW) 134 .addReg(MSP430::SPW).addImm(Amount); 135 } 136 137 if (New) { 138 // The SRW implicit def is dead. 139 New->getOperand(3).setIsDead(); 140 141 // Replace the pseudo instruction with a new instruction... 142 MBB.insert(I, New); 143 } 144 } 145 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 146 // If we are performing frame pointer elimination and if the callee pops 147 // something off the stack pointer, add it back. 148 if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 149 MachineInstr *Old = I; 150 MachineInstr *New = 151 BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 152 MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 153 // The SRW implicit def is dead. 154 New->getOperand(3).setIsDead(); 155 156 MBB.insert(I, New); 157 } 158 } 159 160 MBB.erase(I); 161 } 162 163 void 164 MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 165 int SPAdj, RegScavenger *RS) const { 166 assert(SPAdj == 0 && "Unexpected"); 167 168 unsigned i = 0; 169 MachineInstr &MI = *II; 170 MachineBasicBlock &MBB = *MI.getParent(); 171 MachineFunction &MF = *MBB.getParent(); 172 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 173 DebugLoc dl = MI.getDebugLoc(); 174 while (!MI.getOperand(i).isFI()) { 175 ++i; 176 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 177 } 178 179 int FrameIndex = MI.getOperand(i).getIndex(); 180 181 unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW); 182 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 183 184 // Skip the saved PC 185 Offset += 2; 186 187 if (!TFI->hasFP(MF)) 188 Offset += MF.getFrameInfo()->getStackSize(); 189 else 190 Offset += 2; // Skip the saved FPW 191 192 // Fold imm into offset 193 Offset += MI.getOperand(i+1).getImm(); 194 195 if (MI.getOpcode() == MSP430::ADD16ri) { 196 // This is actually "load effective address" of the stack slot 197 // instruction. We have only two-address instructions, thus we need to 198 // expand it into mov + add 199 200 MI.setDesc(TII.get(MSP430::MOV16rr)); 201 MI.getOperand(i).ChangeToRegister(BasePtr, false); 202 203 if (Offset == 0) 204 return; 205 206 // We need to materialize the offset via add instruction. 207 unsigned DstReg = MI.getOperand(0).getReg(); 208 if (Offset < 0) 209 BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg) 210 .addReg(DstReg).addImm(-Offset); 211 else 212 BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg) 213 .addReg(DstReg).addImm(Offset); 214 215 return; 216 } 217 218 MI.getOperand(i).ChangeToRegister(BasePtr, false); 219 MI.getOperand(i+1).ChangeToImmediate(Offset); 220 } 221 222 void 223 MSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) 224 const { 225 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 226 227 // Create a frame entry for the FPW register that must be saved. 228 if (TFI->hasFP(MF)) { 229 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 230 (void)FrameIdx; 231 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 232 "Slot for FPW register must be last in order to be found!"); 233 } 234 } 235 236 unsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 237 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 238 239 return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW; 240 } 241