Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 1 | //=======- MSP430FrameInfo.cpp - MSP430 Frame Information ------*- C++ -*-====// |
| 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 TargetFrameInfo class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "MSP430FrameInfo.h" |
| 15 | #include "MSP430InstrInfo.h" |
| 16 | #include "MSP430MachineFunctionInfo.h" |
| 17 | #include "llvm/Function.h" |
| 18 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| 19 | #include "llvm/CodeGen/MachineFunction.h" |
| 20 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 21 | #include "llvm/CodeGen/MachineModuleInfo.h" |
| 22 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 23 | #include "llvm/Target/TargetData.h" |
| 24 | #include "llvm/Target/TargetOptions.h" |
| 25 | #include "llvm/Support/CommandLine.h" |
| 26 | |
| 27 | using namespace llvm; |
| 28 | |
| 29 | void MSP430FrameInfo::emitPrologue(MachineFunction &MF) const { |
| 30 | MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB |
| 31 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 32 | MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); |
| 33 | const MSP430RegisterInfo *RegInfo = |
| 34 | static_cast<const MSP430RegisterInfo*>(MF.getTarget().getRegisterInfo()); |
| 35 | const MSP430InstrInfo &TII = |
| 36 | *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); |
| 37 | |
| 38 | MachineBasicBlock::iterator MBBI = MBB.begin(); |
| 39 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); |
| 40 | |
| 41 | // Get the number of bytes to allocate from the FrameInfo. |
| 42 | uint64_t StackSize = MFI->getStackSize(); |
| 43 | |
| 44 | uint64_t NumBytes = 0; |
| 45 | if (RegInfo->hasFP(MF)) { |
| 46 | // Calculate required stack adjustment |
| 47 | uint64_t FrameSize = StackSize - 2; |
| 48 | NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); |
| 49 | |
| 50 | // Get the offset of the stack slot for the EBP register... which is |
| 51 | // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. |
| 52 | // Update the frame offset adjustment. |
| 53 | MFI->setOffsetAdjustment(-NumBytes); |
| 54 | |
| 55 | // Save FPW into the appropriate stack slot... |
| 56 | BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) |
| 57 | .addReg(MSP430::FPW, RegState::Kill); |
| 58 | |
| 59 | // Update FPW with the new base value... |
| 60 | BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) |
| 61 | .addReg(MSP430::SPW); |
| 62 | |
| 63 | // Mark the FramePtr as live-in in every block except the entry. |
| 64 | for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); |
| 65 | I != E; ++I) |
| 66 | I->addLiveIn(MSP430::FPW); |
| 67 | |
| 68 | } else |
| 69 | NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); |
| 70 | |
| 71 | // Skip the callee-saved push instructions. |
| 72 | while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) |
| 73 | ++MBBI; |
| 74 | |
| 75 | if (MBBI != MBB.end()) |
| 76 | DL = MBBI->getDebugLoc(); |
| 77 | |
| 78 | if (NumBytes) { // adjust stack pointer: SPW -= numbytes |
| 79 | // If there is an SUB16ri of SPW immediately before this instruction, merge |
| 80 | // the two. |
| 81 | //NumBytes -= mergeSPUpdates(MBB, MBBI, true); |
| 82 | // If there is an ADD16ri or SUB16ri of SPW immediately after this |
| 83 | // instruction, merge the two instructions. |
| 84 | // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); |
| 85 | |
| 86 | if (NumBytes) { |
| 87 | MachineInstr *MI = |
| 88 | BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) |
| 89 | .addReg(MSP430::SPW).addImm(NumBytes); |
| 90 | // The SRW implicit def is dead. |
| 91 | MI->getOperand(3).setIsDead(); |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | void MSP430FrameInfo::emitEpilogue(MachineFunction &MF, |
| 97 | MachineBasicBlock &MBB) const { |
| 98 | const MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 99 | MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); |
| 100 | const MSP430RegisterInfo *RegInfo = |
| 101 | static_cast<const MSP430RegisterInfo*>(MF.getTarget().getRegisterInfo()); |
| 102 | const MSP430InstrInfo &TII = |
| 103 | *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); |
| 104 | |
| 105 | MachineBasicBlock::iterator MBBI = prior(MBB.end()); |
| 106 | unsigned RetOpcode = MBBI->getOpcode(); |
| 107 | DebugLoc DL = MBBI->getDebugLoc(); |
| 108 | |
| 109 | switch (RetOpcode) { |
| 110 | case MSP430::RET: |
| 111 | case MSP430::RETI: break; // These are ok |
| 112 | default: |
| 113 | llvm_unreachable("Can only insert epilog into returning blocks"); |
| 114 | } |
| 115 | |
| 116 | // Get the number of bytes to allocate from the FrameInfo |
| 117 | uint64_t StackSize = MFI->getStackSize(); |
| 118 | unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); |
| 119 | uint64_t NumBytes = 0; |
| 120 | |
| 121 | if (RegInfo->hasFP(MF)) { |
| 122 | // Calculate required stack adjustment |
| 123 | uint64_t FrameSize = StackSize - 2; |
| 124 | NumBytes = FrameSize - CSSize; |
| 125 | |
| 126 | // pop FPW. |
| 127 | BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); |
| 128 | } else |
| 129 | NumBytes = StackSize - CSSize; |
| 130 | |
| 131 | // Skip the callee-saved pop instructions. |
| 132 | while (MBBI != MBB.begin()) { |
| 133 | MachineBasicBlock::iterator PI = prior(MBBI); |
| 134 | unsigned Opc = PI->getOpcode(); |
| 135 | if (Opc != MSP430::POP16r && !PI->getDesc().isTerminator()) |
| 136 | break; |
| 137 | --MBBI; |
| 138 | } |
| 139 | |
| 140 | DL = MBBI->getDebugLoc(); |
| 141 | |
| 142 | // If there is an ADD16ri or SUB16ri of SPW immediately before this |
| 143 | // instruction, merge the two instructions. |
| 144 | //if (NumBytes || MFI->hasVarSizedObjects()) |
| 145 | // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); |
| 146 | |
| 147 | if (MFI->hasVarSizedObjects()) { |
| 148 | BuildMI(MBB, MBBI, DL, |
| 149 | TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); |
| 150 | if (CSSize) { |
| 151 | MachineInstr *MI = |
| 152 | BuildMI(MBB, MBBI, DL, |
| 153 | TII.get(MSP430::SUB16ri), MSP430::SPW) |
| 154 | .addReg(MSP430::SPW).addImm(CSSize); |
| 155 | // The SRW implicit def is dead. |
| 156 | MI->getOperand(3).setIsDead(); |
| 157 | } |
| 158 | } else { |
| 159 | // adjust stack pointer back: SPW += numbytes |
| 160 | if (NumBytes) { |
| 161 | MachineInstr *MI = |
| 162 | BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) |
| 163 | .addReg(MSP430::SPW).addImm(NumBytes); |
| 164 | // The SRW implicit def is dead. |
| 165 | MI->getOperand(3).setIsDead(); |
| 166 | } |
| 167 | } |
| 168 | } |