| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 1 | //===-- MipsSEFrameLowering.cpp - Mips32/64 Frame 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 Mips32/64 implementation of TargetFrameLowering class. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "MipsSEFrameLowering.h" | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 15 | #include "MCTargetDesc/MipsBaseInfo.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 16 | #include "MipsAnalyzeImmediate.h" | 
|  | 17 | #include "MipsMachineFunction.h" | 
|  | 18 | #include "MipsSEInstrInfo.h" | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
|  | 20 | #include "llvm/CodeGen/MachineFunction.h" | 
|  | 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
|  | 22 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
|  | 23 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Akira Hatanaka | 5852e3b | 2012-11-03 00:05:43 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/RegisterScavenging.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 25 | #include "llvm/IR/DataLayout.h" | 
|  | 26 | #include "llvm/IR/Function.h" | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 27 | #include "llvm/Support/CommandLine.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetOptions.h" | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 29 |  | 
|  | 30 | using namespace llvm; | 
|  | 31 |  | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 32 | namespace { | 
|  | 33 | typedef MachineBasicBlock::iterator Iter; | 
|  | 34 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 35 | /// Helper class to expand pseudos. | 
|  | 36 | class ExpandPseudo { | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 37 | public: | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 38 | ExpandPseudo(MachineFunction &MF); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 39 | bool expand(); | 
|  | 40 |  | 
|  | 41 | private: | 
|  | 42 | bool expandInstr(MachineBasicBlock &MBB, Iter I); | 
| Akira Hatanaka | 5705f54 | 2013-05-02 23:07:05 +0000 | [diff] [blame] | 43 | void expandLoadCCond(MachineBasicBlock &MBB, Iter I); | 
|  | 44 | void expandStoreCCond(MachineBasicBlock &MBB, Iter I); | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 45 | void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); | 
|  | 46 | void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 47 | bool expandCopy(MachineBasicBlock &MBB, Iter I); | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 48 | bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, | 
|  | 49 | unsigned Src, unsigned RegSize); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 50 |  | 
|  | 51 | MachineFunction &MF; | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 52 | MachineRegisterInfo &MRI; | 
|  | 53 | }; | 
|  | 54 | } | 
|  | 55 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 56 | ExpandPseudo::ExpandPseudo(MachineFunction &MF_) | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 57 | : MF(MF_), MRI(MF.getRegInfo()) {} | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 58 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 59 | bool ExpandPseudo::expand() { | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 60 | bool Expanded = false; | 
|  | 61 |  | 
|  | 62 | for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end(); | 
|  | 63 | BB != BBEnd; ++BB) | 
|  | 64 | for (Iter I = BB->begin(), End = BB->end(); I != End;) | 
|  | 65 | Expanded |= expandInstr(*BB, I++); | 
|  | 66 |  | 
|  | 67 | return Expanded; | 
|  | 68 | } | 
|  | 69 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 70 | bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 71 | switch(I->getOpcode()) { | 
| Akira Hatanaka | 5705f54 | 2013-05-02 23:07:05 +0000 | [diff] [blame] | 72 | case Mips::LOAD_CCOND_DSP: | 
|  | 73 | case Mips::LOAD_CCOND_DSP_P8: | 
|  | 74 | expandLoadCCond(MBB, I); | 
|  | 75 | break; | 
|  | 76 | case Mips::STORE_CCOND_DSP: | 
|  | 77 | case Mips::STORE_CCOND_DSP_P8: | 
|  | 78 | expandStoreCCond(MBB, I); | 
|  | 79 | break; | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 80 | case Mips::LOAD_AC64: | 
|  | 81 | case Mips::LOAD_AC64_P8: | 
|  | 82 | case Mips::LOAD_AC_DSP: | 
|  | 83 | case Mips::LOAD_AC_DSP_P8: | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 84 | expandLoadACC(MBB, I, 4); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 85 | break; | 
|  | 86 | case Mips::LOAD_AC128: | 
|  | 87 | case Mips::LOAD_AC128_P8: | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 88 | expandLoadACC(MBB, I, 8); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 89 | break; | 
|  | 90 | case Mips::STORE_AC64: | 
|  | 91 | case Mips::STORE_AC64_P8: | 
|  | 92 | case Mips::STORE_AC_DSP: | 
|  | 93 | case Mips::STORE_AC_DSP_P8: | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 94 | expandStoreACC(MBB, I, 4); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 95 | break; | 
|  | 96 | case Mips::STORE_AC128: | 
|  | 97 | case Mips::STORE_AC128_P8: | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 98 | expandStoreACC(MBB, I, 8); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 99 | break; | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 100 | case TargetOpcode::COPY: | 
|  | 101 | if (!expandCopy(MBB, I)) | 
|  | 102 | return false; | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 103 | break; | 
|  | 104 | default: | 
|  | 105 | return false; | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 | MBB.erase(I); | 
|  | 109 | return true; | 
|  | 110 | } | 
|  | 111 |  | 
| Akira Hatanaka | 5705f54 | 2013-05-02 23:07:05 +0000 | [diff] [blame] | 112 | void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) { | 
|  | 113 | //  load $vr, FI | 
|  | 114 | //  copy ccond, $vr | 
|  | 115 |  | 
|  | 116 | assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); | 
|  | 117 |  | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 118 | const MipsSEInstrInfo &TII = | 
|  | 119 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 120 | const MipsRegisterInfo &RegInfo = | 
|  | 121 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 122 |  | 
| Akira Hatanaka | 5705f54 | 2013-05-02 23:07:05 +0000 | [diff] [blame] | 123 | const TargetRegisterClass *RC = RegInfo.intRegClass(4); | 
|  | 124 | unsigned VR = MRI.createVirtualRegister(RC); | 
|  | 125 | unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); | 
|  | 126 |  | 
|  | 127 | TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0); | 
|  | 128 | BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst) | 
|  | 129 | .addReg(VR, RegState::Kill); | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) { | 
|  | 133 | //  copy $vr, ccond | 
|  | 134 | //  store $vr, FI | 
|  | 135 |  | 
|  | 136 | assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); | 
|  | 137 |  | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 138 | const MipsSEInstrInfo &TII = | 
|  | 139 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 140 | const MipsRegisterInfo &RegInfo = | 
|  | 141 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 142 |  | 
| Akira Hatanaka | 5705f54 | 2013-05-02 23:07:05 +0000 | [diff] [blame] | 143 | const TargetRegisterClass *RC = RegInfo.intRegClass(4); | 
|  | 144 | unsigned VR = MRI.createVirtualRegister(RC); | 
|  | 145 | unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); | 
|  | 146 |  | 
|  | 147 | BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR) | 
|  | 148 | .addReg(Src, getKillRegState(I->getOperand(0).isKill())); | 
|  | 149 | TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0); | 
|  | 150 | } | 
|  | 151 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 152 | void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 153 | unsigned RegSize) { | 
|  | 154 | //  load $vr0, FI | 
|  | 155 | //  copy lo, $vr0 | 
|  | 156 | //  load $vr1, FI + 4 | 
|  | 157 | //  copy hi, $vr1 | 
|  | 158 |  | 
|  | 159 | assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); | 
|  | 160 |  | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 161 | const MipsSEInstrInfo &TII = | 
|  | 162 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 163 | const MipsRegisterInfo &RegInfo = | 
|  | 164 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 165 |  | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 166 | const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); | 
|  | 167 | unsigned VR0 = MRI.createVirtualRegister(RC); | 
|  | 168 | unsigned VR1 = MRI.createVirtualRegister(RC); | 
|  | 169 | unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); | 
|  | 170 | unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo); | 
|  | 171 | unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi); | 
|  | 172 | DebugLoc DL = I->getDebugLoc(); | 
|  | 173 | const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); | 
|  | 174 |  | 
|  | 175 | TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0); | 
|  | 176 | BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill); | 
|  | 177 | TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize); | 
|  | 178 | BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill); | 
|  | 179 | } | 
|  | 180 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 181 | void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I, | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 182 | unsigned RegSize) { | 
|  | 183 | //  copy $vr0, lo | 
|  | 184 | //  store $vr0, FI | 
|  | 185 | //  copy $vr1, hi | 
|  | 186 | //  store $vr1, FI + 4 | 
|  | 187 |  | 
|  | 188 | assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); | 
|  | 189 |  | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 190 | const MipsSEInstrInfo &TII = | 
|  | 191 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 192 | const MipsRegisterInfo &RegInfo = | 
|  | 193 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 194 |  | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 195 | const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); | 
|  | 196 | unsigned VR0 = MRI.createVirtualRegister(RC); | 
|  | 197 | unsigned VR1 = MRI.createVirtualRegister(RC); | 
|  | 198 | unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); | 
|  | 199 | unsigned SrcKill = getKillRegState(I->getOperand(0).isKill()); | 
|  | 200 | unsigned Lo = RegInfo.getSubReg(Src, Mips::sub_lo); | 
|  | 201 | unsigned Hi = RegInfo.getSubReg(Src, Mips::sub_hi); | 
|  | 202 | DebugLoc DL = I->getDebugLoc(); | 
|  | 203 |  | 
|  | 204 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(Lo, SrcKill); | 
|  | 205 | TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0); | 
|  | 206 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(Hi, SrcKill); | 
|  | 207 | TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize); | 
|  | 208 | } | 
|  | 209 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 210 | bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) { | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 211 | unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 212 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 213 | if (Mips::ACRegsDSPRegClass.contains(Dst, Src)) | 
|  | 214 | return expandCopyACC(MBB, I, Dst, Src, 4); | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 215 |  | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 216 | if (Mips::ACRegs128RegClass.contains(Dst, Src)) | 
|  | 217 | return expandCopyACC(MBB, I, Dst, Src, 8); | 
|  | 218 |  | 
|  | 219 | return false; | 
|  | 220 | } | 
|  | 221 |  | 
|  | 222 | bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, | 
|  | 223 | unsigned Src, unsigned RegSize) { | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 224 | //  copy $vr0, src_lo | 
|  | 225 | //  copy dst_lo, $vr0 | 
|  | 226 | //  copy $vr1, src_hi | 
|  | 227 | //  copy dst_hi, $vr1 | 
|  | 228 |  | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 229 | const MipsSEInstrInfo &TII = | 
|  | 230 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 231 | const MipsRegisterInfo &RegInfo = | 
|  | 232 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 233 |  | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 234 | const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); | 
|  | 235 | unsigned VR0 = MRI.createVirtualRegister(RC); | 
|  | 236 | unsigned VR1 = MRI.createVirtualRegister(RC); | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 237 | unsigned SrcKill = getKillRegState(I->getOperand(1).isKill()); | 
|  | 238 | unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo); | 
|  | 239 | unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi); | 
|  | 240 | unsigned SrcLo = RegInfo.getSubReg(Src, Mips::sub_lo); | 
|  | 241 | unsigned SrcHi = RegInfo.getSubReg(Src, Mips::sub_hi); | 
|  | 242 | DebugLoc DL = I->getDebugLoc(); | 
|  | 243 |  | 
|  | 244 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(SrcLo, SrcKill); | 
|  | 245 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo) | 
|  | 246 | .addReg(VR0, RegState::Kill); | 
|  | 247 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill); | 
|  | 248 | BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi) | 
|  | 249 | .addReg(VR1, RegState::Kill); | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 250 | return true; | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 251 | } | 
|  | 252 |  | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 253 | unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { | 
|  | 254 | static const unsigned EhDataReg[] = { | 
|  | 255 | Mips::A0, Mips::A1, Mips::A2, Mips::A3 | 
|  | 256 | }; | 
|  | 257 | static const unsigned EhDataReg64[] = { | 
|  | 258 | Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 | 
|  | 259 | }; | 
|  | 260 |  | 
|  | 261 | return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; | 
|  | 262 | } | 
|  | 263 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 264 | void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { | 
|  | 265 | MachineBasicBlock &MBB   = MF.front(); | 
|  | 266 | MachineFrameInfo *MFI    = MF.getFrameInfo(); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 267 | MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 268 |  | 
| Akira Hatanaka | 88d76cf | 2012-07-31 23:52:55 +0000 | [diff] [blame] | 269 | const MipsSEInstrInfo &TII = | 
|  | 270 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 271 | const MipsRegisterInfo &RegInfo = | 
|  | 272 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 273 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 274 | MachineBasicBlock::iterator MBBI = MBB.begin(); | 
|  | 275 | DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); | 
|  | 276 | unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; | 
|  | 277 | unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; | 
|  | 278 | unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; | 
|  | 279 | unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 280 |  | 
|  | 281 | // First, compute final stack size. | 
|  | 282 | uint64_t StackSize = MFI->getStackSize(); | 
|  | 283 |  | 
|  | 284 | // No need to allocate space on the stack. | 
|  | 285 | if (StackSize == 0 && !MFI->adjustsStack()) return; | 
|  | 286 |  | 
|  | 287 | MachineModuleInfo &MMI = MF.getMMI(); | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 288 | const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 289 | MachineLocation DstML, SrcML; | 
|  | 290 |  | 
|  | 291 | // Adjust stack. | 
| Akira Hatanaka | 88d76cf | 2012-07-31 23:52:55 +0000 | [diff] [blame] | 292 | TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 293 |  | 
|  | 294 | // emit ".cfi_def_cfa_offset StackSize" | 
|  | 295 | MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); | 
|  | 296 | BuildMI(MBB, MBBI, dl, | 
|  | 297 | TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 298 | MMI.addFrameInst( | 
|  | 299 | MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 300 |  | 
|  | 301 | const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); | 
|  | 302 |  | 
|  | 303 | if (CSI.size()) { | 
|  | 304 | // Find the instruction past the last instruction that saves a callee-saved | 
|  | 305 | // register to the stack. | 
|  | 306 | for (unsigned i = 0; i < CSI.size(); ++i) | 
|  | 307 | ++MBBI; | 
|  | 308 |  | 
|  | 309 | // Iterate over list of callee-saved registers and emit .cfi_offset | 
|  | 310 | // directives. | 
|  | 311 | MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); | 
|  | 312 | BuildMI(MBB, MBBI, dl, | 
|  | 313 | TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); | 
|  | 314 |  | 
|  | 315 | for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), | 
|  | 316 | E = CSI.end(); I != E; ++I) { | 
|  | 317 | int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); | 
|  | 318 | unsigned Reg = I->getReg(); | 
|  | 319 |  | 
|  | 320 | // If Reg is a double precision register, emit two cfa_offsets, | 
|  | 321 | // one for each of the paired single precision registers. | 
|  | 322 | if (Mips::AFGR64RegClass.contains(Reg)) { | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 323 | unsigned Reg0 = | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 324 | MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true); | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 325 | unsigned Reg1 = | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 326 | MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 327 |  | 
|  | 328 | if (!STI.isLittle()) | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 329 | std::swap(Reg0, Reg1); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 330 |  | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 331 | MMI.addFrameInst( | 
|  | 332 | MCCFIInstruction::createOffset(CSLabel, Reg0, Offset)); | 
|  | 333 | MMI.addFrameInst( | 
|  | 334 | MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4)); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 335 | } else { | 
|  | 336 | // Reg is either in CPURegs or FGR32. | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 337 | MMI.addFrameInst(MCCFIInstruction::createOffset( | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 338 | CSLabel, MRI->getDwarfRegNum(Reg, 1), Offset)); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 339 | } | 
|  | 340 | } | 
|  | 341 | } | 
|  | 342 |  | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 343 | if (MipsFI->callsEhReturn()) { | 
|  | 344 | const TargetRegisterClass *RC = STI.isABI_N64() ? | 
|  | 345 | &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; | 
|  | 346 |  | 
|  | 347 | // Insert instructions that spill eh data registers. | 
|  | 348 | for (int I = 0; I < 4; ++I) { | 
|  | 349 | if (!MBB.isLiveIn(ehDataReg(I))) | 
|  | 350 | MBB.addLiveIn(ehDataReg(I)); | 
|  | 351 | TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 352 | MipsFI->getEhDataRegFI(I), RC, &RegInfo); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 353 | } | 
|  | 354 |  | 
|  | 355 | // Emit .cfi_offset directives for eh data registers. | 
|  | 356 | MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); | 
|  | 357 | BuildMI(MBB, MBBI, dl, | 
|  | 358 | TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); | 
|  | 359 | for (int I = 0; I < 4; ++I) { | 
|  | 360 | int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 361 | unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true); | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 362 | MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset)); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 363 | } | 
|  | 364 | } | 
|  | 365 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 366 | // if framepointer enabled, set it to point to the stack pointer. | 
|  | 367 | if (hasFP(MF)) { | 
|  | 368 | // Insert instruction "move $fp, $sp" at this location. | 
|  | 369 | BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); | 
|  | 370 |  | 
|  | 371 | // emit ".cfi_def_cfa_register $fp" | 
|  | 372 | MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); | 
|  | 373 | BuildMI(MBB, MBBI, dl, | 
|  | 374 | TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); | 
| Rafael Espindola | b08d2c2 | 2013-05-16 21:02:15 +0000 | [diff] [blame] | 375 | MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister( | 
| Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 376 | SetFPLabel, MRI->getDwarfRegNum(FP, true))); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 377 | } | 
|  | 378 | } | 
|  | 379 |  | 
|  | 380 | void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, | 
|  | 381 | MachineBasicBlock &MBB) const { | 
|  | 382 | MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); | 
|  | 383 | MachineFrameInfo *MFI            = MF.getFrameInfo(); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 384 | MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 385 |  | 
| Akira Hatanaka | 88d76cf | 2012-07-31 23:52:55 +0000 | [diff] [blame] | 386 | const MipsSEInstrInfo &TII = | 
|  | 387 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 388 | const MipsRegisterInfo &RegInfo = | 
|  | 389 | *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); | 
|  | 390 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 391 | DebugLoc dl = MBBI->getDebugLoc(); | 
|  | 392 | unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; | 
|  | 393 | unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; | 
|  | 394 | unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; | 
|  | 395 | unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 396 |  | 
|  | 397 | // if framepointer enabled, restore the stack pointer. | 
|  | 398 | if (hasFP(MF)) { | 
|  | 399 | // Find the first instruction that restores a callee-saved register. | 
|  | 400 | MachineBasicBlock::iterator I = MBBI; | 
|  | 401 |  | 
|  | 402 | for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) | 
|  | 403 | --I; | 
|  | 404 |  | 
|  | 405 | // Insert instruction "move $sp, $fp" at this location. | 
|  | 406 | BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); | 
|  | 407 | } | 
|  | 408 |  | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 409 | if (MipsFI->callsEhReturn()) { | 
|  | 410 | const TargetRegisterClass *RC = STI.isABI_N64() ? | 
|  | 411 | &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; | 
|  | 412 |  | 
|  | 413 | // Find first instruction that restores a callee-saved register. | 
|  | 414 | MachineBasicBlock::iterator I = MBBI; | 
|  | 415 | for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) | 
|  | 416 | --I; | 
|  | 417 |  | 
|  | 418 | // Insert instructions that restore eh data registers. | 
|  | 419 | for (int J = 0; J < 4; ++J) { | 
|  | 420 | TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), | 
| Bill Wendling | ead89ef | 2013-06-07 07:04:14 +0000 | [diff] [blame] | 421 | RC, &RegInfo); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 422 | } | 
|  | 423 | } | 
|  | 424 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 425 | // Get the number of bytes from FrameInfo | 
|  | 426 | uint64_t StackSize = MFI->getStackSize(); | 
|  | 427 |  | 
|  | 428 | if (!StackSize) | 
|  | 429 | return; | 
|  | 430 |  | 
|  | 431 | // Adjust stack. | 
| Akira Hatanaka | 88d76cf | 2012-07-31 23:52:55 +0000 | [diff] [blame] | 432 | TII.adjustStackPtr(SP, StackSize, MBB, MBBI); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 433 | } | 
|  | 434 |  | 
|  | 435 | bool MipsSEFrameLowering:: | 
|  | 436 | spillCalleeSavedRegisters(MachineBasicBlock &MBB, | 
|  | 437 | MachineBasicBlock::iterator MI, | 
|  | 438 | const std::vector<CalleeSavedInfo> &CSI, | 
|  | 439 | const TargetRegisterInfo *TRI) const { | 
|  | 440 | MachineFunction *MF = MBB.getParent(); | 
|  | 441 | MachineBasicBlock *EntryBlock = MF->begin(); | 
|  | 442 | const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); | 
|  | 443 |  | 
|  | 444 | for (unsigned i = 0, e = CSI.size(); i != e; ++i) { | 
|  | 445 | // Add the callee-saved register as live-in. Do not add if the register is | 
|  | 446 | // RA and return address is taken, because it has already been added in | 
|  | 447 | // method MipsTargetLowering::LowerRETURNADDR. | 
|  | 448 | // It's killed at the spill, unless the register is RA and return address | 
|  | 449 | // is taken. | 
|  | 450 | unsigned Reg = CSI[i].getReg(); | 
|  | 451 | bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) | 
|  | 452 | && MF->getFrameInfo()->isReturnAddressTaken(); | 
|  | 453 | if (!IsRAAndRetAddrIsTaken) | 
|  | 454 | EntryBlock->addLiveIn(Reg); | 
|  | 455 |  | 
|  | 456 | // Insert the spill to the stack frame. | 
|  | 457 | bool IsKill = !IsRAAndRetAddrIsTaken; | 
|  | 458 | const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); | 
|  | 459 | TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, | 
|  | 460 | CSI[i].getFrameIdx(), RC, TRI); | 
|  | 461 | } | 
|  | 462 |  | 
|  | 463 | return true; | 
|  | 464 | } | 
|  | 465 |  | 
|  | 466 | bool | 
|  | 467 | MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { | 
|  | 468 | const MachineFrameInfo *MFI = MF.getFrameInfo(); | 
|  | 469 |  | 
|  | 470 | // Reserve call frame if the size of the maximum call frame fits into 16-bit | 
|  | 471 | // immediate field and there are no variable sized objects on the stack. | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 472 | // Make sure the second register scavenger spill slot can be accessed with one | 
|  | 473 | // instruction. | 
|  | 474 | return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) && | 
|  | 475 | !MFI->hasVarSizedObjects(); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 476 | } | 
|  | 477 |  | 
| Eli Bendersky | 8da8716 | 2013-02-21 20:05:00 +0000 | [diff] [blame] | 478 | // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions | 
|  | 479 | void MipsSEFrameLowering:: | 
|  | 480 | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, | 
|  | 481 | MachineBasicBlock::iterator I) const { | 
|  | 482 | const MipsSEInstrInfo &TII = | 
|  | 483 | *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); | 
|  | 484 |  | 
|  | 485 | if (!hasReservedCallFrame(MF)) { | 
|  | 486 | int64_t Amount = I->getOperand(0).getImm(); | 
|  | 487 |  | 
|  | 488 | if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) | 
|  | 489 | Amount = -Amount; | 
|  | 490 |  | 
|  | 491 | unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; | 
|  | 492 | TII.adjustStackPtr(SP, Amount, MBB, I); | 
|  | 493 | } | 
|  | 494 |  | 
|  | 495 | MBB.erase(I); | 
|  | 496 | } | 
|  | 497 |  | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 498 | void MipsSEFrameLowering:: | 
|  | 499 | processFunctionBeforeCalleeSavedScan(MachineFunction &MF, | 
|  | 500 | RegScavenger *RS) const { | 
|  | 501 | MachineRegisterInfo &MRI = MF.getRegInfo(); | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 502 | MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 503 | unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; | 
|  | 504 |  | 
|  | 505 | // Mark $fp as used if function has dedicated frame pointer. | 
|  | 506 | if (hasFP(MF)) | 
|  | 507 | MRI.setPhysRegUsed(FP); | 
| Akira Hatanaka | 5852e3b | 2012-11-03 00:05:43 +0000 | [diff] [blame] | 508 |  | 
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 509 | // Create spill slots for eh data registers if function calls eh_return. | 
|  | 510 | if (MipsFI->callsEhReturn()) | 
|  | 511 | MipsFI->createEhDataRegsFI(); | 
|  | 512 |  | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 513 | // Expand pseudo instructions which load, store or copy accumulators. | 
|  | 514 | // Add an emergency spill slot if a pseudo was expanded. | 
| Akira Hatanaka | ae4a556 | 2013-05-01 23:41:31 +0000 | [diff] [blame] | 515 | if (ExpandPseudo(MF).expand()) { | 
| Akira Hatanaka | 3b70145 | 2013-03-30 01:04:11 +0000 | [diff] [blame] | 516 | // The spill slot should be half the size of the accumulator. If target is | 
|  | 517 | // mips64, it should be 64-bit, otherwise it should be 32-bt. | 
|  | 518 | const TargetRegisterClass *RC = STI.hasMips64() ? | 
|  | 519 | &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; | 
|  | 520 | int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), | 
|  | 521 | RC->getAlignment(), false); | 
|  | 522 | RS->addScavengingFrameIndex(FI); | 
|  | 523 | } | 
|  | 524 |  | 
| Akira Hatanaka | 5852e3b | 2012-11-03 00:05:43 +0000 | [diff] [blame] | 525 | // Set scavenging frame index if necessary. | 
|  | 526 | uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() + | 
|  | 527 | estimateStackSize(MF); | 
|  | 528 |  | 
|  | 529 | if (isInt<16>(MaxSPOffset)) | 
|  | 530 | return; | 
|  | 531 |  | 
|  | 532 | const TargetRegisterClass *RC = STI.isABI_N64() ? | 
|  | 533 | &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; | 
|  | 534 | int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), | 
|  | 535 | RC->getAlignment(), false); | 
| Hal Finkel | 9e331c2 | 2013-03-22 23:32:27 +0000 | [diff] [blame] | 536 | RS->addScavengingFrameIndex(FI); | 
| Akira Hatanaka | d1c43ce | 2012-07-31 22:50:19 +0000 | [diff] [blame] | 537 | } | 
| Akira Hatanaka | fab8929 | 2012-08-02 18:21:47 +0000 | [diff] [blame] | 538 |  | 
|  | 539 | const MipsFrameLowering * | 
|  | 540 | llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { | 
|  | 541 | return new MipsSEFrameLowering(ST); | 
|  | 542 | } |