Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 1 | //===- SparcRegisterInfo.cpp - SPARC Register Information -------*- C++ -*-===// |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame] | 2 | // |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame] | 7 | // |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 10 | // This file contains the SPARC implementation of the MRegisterInfo class. |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 14 | #include "Sparc.h" |
| 15 | #include "SparcRegisterInfo.h" |
| 16 | #include "SparcSubtarget.h" |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 18 | #include "llvm/CodeGen/MachineFunction.h" |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/MachineFrameInfo.h" |
Jim Laskey | f1d78e8 | 2006-03-23 18:12:57 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MachineLocation.h" |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 21 | #include "llvm/Target/TargetInstrInfo.h" |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 22 | #include "llvm/Type.h" |
Evan Cheng | b371f45 | 2007-02-19 21:49:54 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/BitVector.h" |
Brian Gaeke | 74dfcf1 | 2004-09-02 02:37:43 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/STLExtras.h" |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 25 | using namespace llvm; |
| 26 | |
Evan Cheng | 7ce4578 | 2006-11-13 23:36:35 +0000 | [diff] [blame] | 27 | SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st, |
| 28 | const TargetInstrInfo &tii) |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 29 | : SparcGenRegisterInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP), |
Evan Cheng | 7ce4578 | 2006-11-13 23:36:35 +0000 | [diff] [blame] | 30 | Subtarget(st), TII(tii) { |
Chris Lattner | 69d3909 | 2006-02-04 06:58:46 +0000 | [diff] [blame] | 31 | } |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 32 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 33 | void SparcRegisterInfo:: |
Chris Lattner | 57f1b67 | 2004-08-15 21:56:44 +0000 | [diff] [blame] | 34 | storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 35 | unsigned SrcReg, bool isKill, int FI, |
Chris Lattner | 331355c | 2005-12-17 20:18:49 +0000 | [diff] [blame] | 36 | const TargetRegisterClass *RC) const { |
Brian Gaeke | 6713d98 | 2004-06-17 22:34:48 +0000 | [diff] [blame] | 37 | // On the order of operands here: think "[FrameIdx + 0] = SrcReg". |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 38 | if (RC == SP::IntRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 39 | BuildMI(MBB, I, TII.get(SP::STri)).addFrameIndex(FI).addImm(0) |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 40 | .addReg(SrcReg, false, false, isKill); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 41 | else if (RC == SP::FPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 42 | BuildMI(MBB, I, TII.get(SP::STFri)).addFrameIndex(FI).addImm(0) |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 43 | .addReg(SrcReg, false, false, isKill); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 44 | else if (RC == SP::DFPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 45 | BuildMI(MBB, I, TII.get(SP::STDFri)).addFrameIndex(FI).addImm(0) |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 46 | .addReg(SrcReg, false, false, isKill); |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 47 | else |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 48 | assert(0 && "Can't store this register to stack slot"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 49 | } |
| 50 | |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 51 | void SparcRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 52 | bool isKill, |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 53 | SmallVectorImpl<MachineOperand> &Addr, |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 54 | const TargetRegisterClass *RC, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 55 | SmallVectorImpl<MachineInstr*> &NewMIs) const { |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 56 | unsigned Opc = 0; |
| 57 | if (RC == SP::IntRegsRegisterClass) |
| 58 | Opc = SP::STri; |
| 59 | else if (RC == SP::FPRegsRegisterClass) |
| 60 | Opc = SP::STFri; |
| 61 | else if (RC == SP::DFPRegsRegisterClass) |
| 62 | Opc = SP::STDFri; |
| 63 | else |
| 64 | assert(0 && "Can't load this register"); |
| 65 | MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); |
| 66 | for (unsigned i = 0, e = Addr.size(); i != e; ++i) { |
| 67 | MachineOperand &MO = Addr[i]; |
| 68 | if (MO.isRegister()) |
| 69 | MIB.addReg(MO.getReg()); |
| 70 | else if (MO.isImmediate()) |
| 71 | MIB.addImm(MO.getImmedValue()); |
| 72 | else |
| 73 | MIB.addFrameIndex(MO.getFrameIndex()); |
| 74 | } |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 75 | MIB.addReg(SrcReg, false, false, isKill); |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 76 | NewMIs.push_back(MIB); |
| 77 | return; |
| 78 | } |
| 79 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 80 | void SparcRegisterInfo:: |
Chris Lattner | 57f1b67 | 2004-08-15 21:56:44 +0000 | [diff] [blame] | 81 | loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 82 | unsigned DestReg, int FI, |
Chris Lattner | 331355c | 2005-12-17 20:18:49 +0000 | [diff] [blame] | 83 | const TargetRegisterClass *RC) const { |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 84 | if (RC == SP::IntRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 85 | BuildMI(MBB, I, TII.get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 86 | else if (RC == SP::FPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 87 | BuildMI(MBB, I, TII.get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 88 | else if (RC == SP::DFPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 89 | BuildMI(MBB, I, TII.get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 90 | else |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 91 | assert(0 && "Can't load this register from stack slot"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 92 | } |
| 93 | |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 94 | void SparcRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 95 | SmallVectorImpl<MachineOperand> &Addr, |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 96 | const TargetRegisterClass *RC, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 97 | SmallVectorImpl<MachineInstr*> &NewMIs) const { |
Evan Cheng | 66f0f64 | 2007-10-05 01:32:41 +0000 | [diff] [blame] | 98 | unsigned Opc = 0; |
| 99 | if (RC == SP::IntRegsRegisterClass) |
| 100 | Opc = SP::LDri; |
| 101 | else if (RC == SP::FPRegsRegisterClass) |
| 102 | Opc = SP::LDFri; |
| 103 | else if (RC == SP::DFPRegsRegisterClass) |
| 104 | Opc = SP::LDDFri; |
| 105 | else |
| 106 | assert(0 && "Can't load this register"); |
| 107 | MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); |
| 108 | for (unsigned i = 0, e = Addr.size(); i != e; ++i) { |
| 109 | MachineOperand &MO = Addr[i]; |
| 110 | if (MO.isRegister()) |
| 111 | MIB.addReg(MO.getReg()); |
| 112 | else if (MO.isImmediate()) |
| 113 | MIB.addImm(MO.getImmedValue()); |
| 114 | else |
| 115 | MIB.addFrameIndex(MO.getFrameIndex()); |
| 116 | } |
| 117 | NewMIs.push_back(MIB); |
| 118 | return; |
| 119 | } |
| 120 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 121 | void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, |
| 122 | MachineBasicBlock::iterator I, |
| 123 | unsigned DestReg, unsigned SrcReg, |
Evan Cheng | 9efce63 | 2007-09-26 06:25:56 +0000 | [diff] [blame] | 124 | const TargetRegisterClass *DestRC, |
| 125 | const TargetRegisterClass *SrcRC) const { |
| 126 | if (DestRC != SrcRC) { |
| 127 | cerr << "Not yet supported!"; |
| 128 | abort(); |
| 129 | } |
| 130 | |
| 131 | if (DestRC == SP::IntRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 132 | BuildMI(MBB, I, TII.get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); |
Evan Cheng | 9efce63 | 2007-09-26 06:25:56 +0000 | [diff] [blame] | 133 | else if (DestRC == SP::FPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 134 | BuildMI(MBB, I, TII.get(SP::FMOVS), DestReg).addReg(SrcReg); |
Evan Cheng | 9efce63 | 2007-09-26 06:25:56 +0000 | [diff] [blame] | 135 | else if (DestRC == SP::DFPRegsRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 136 | BuildMI(MBB, I, TII.get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) |
| 137 | .addReg(SrcReg); |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 138 | else |
| 139 | assert (0 && "Can't copy this register"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 140 | } |
| 141 | |
Evan Cheng | bf2c8b3 | 2007-03-20 08:09:38 +0000 | [diff] [blame] | 142 | void SparcRegisterInfo::reMaterialize(MachineBasicBlock &MBB, |
| 143 | MachineBasicBlock::iterator I, |
| 144 | unsigned DestReg, |
| 145 | const MachineInstr *Orig) const { |
| 146 | MachineInstr *MI = Orig->clone(); |
| 147 | MI->getOperand(0).setReg(DestReg); |
| 148 | MBB.insert(I, MI); |
| 149 | } |
| 150 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 151 | MachineInstr *SparcRegisterInfo::foldMemoryOperand(MachineInstr* MI, |
Evan Cheng | aee4af6 | 2007-12-02 08:30:39 +0000 | [diff] [blame] | 152 | SmallVectorImpl<unsigned> &Ops, |
| 153 | int FI) const { |
| 154 | if (Ops.size() != 1) return NULL; |
| 155 | |
| 156 | unsigned OpNum = Ops[0]; |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 157 | bool isFloat = false; |
Evan Cheng | 6ce7dc2 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 158 | MachineInstr *NewMI = NULL; |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 159 | switch (MI->getOpcode()) { |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 160 | case SP::ORrr: |
| 161 | if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == SP::G0&& |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 162 | MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) { |
| 163 | if (OpNum == 0) // COPY -> STORE |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 164 | NewMI = BuildMI(TII.get(SP::STri)).addFrameIndex(FI).addImm(0) |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 165 | .addReg(MI->getOperand(2).getReg()); |
| 166 | else // COPY -> LOAD |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 167 | NewMI = BuildMI(TII.get(SP::LDri), MI->getOperand(0).getReg()) |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 168 | .addFrameIndex(FI).addImm(0); |
| 169 | } |
| 170 | break; |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 171 | case SP::FMOVS: |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 172 | isFloat = true; |
| 173 | // FALLTHROUGH |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 174 | case SP::FMOVD: |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 175 | if (OpNum == 0) // COPY -> STORE |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 176 | NewMI = BuildMI(TII.get(isFloat ? SP::STFri : SP::STDFri)) |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 177 | .addFrameIndex(FI).addImm(0).addReg(MI->getOperand(1).getReg()); |
| 178 | else // COPY -> LOAD |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 179 | NewMI = BuildMI(TII.get(isFloat ? SP::LDFri : SP::LDDFri), |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 180 | MI->getOperand(0).getReg()).addFrameIndex(FI).addImm(0); |
| 181 | break; |
| 182 | } |
Evan Cheng | 6ce7dc2 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 183 | |
| 184 | if (NewMI) |
| 185 | NewMI->copyKillDeadInfo(MI); |
| 186 | return NewMI; |
Chris Lattner | 6184f9c | 2006-02-03 07:06:25 +0000 | [diff] [blame] | 187 | } |
| 188 | |
Anton Korobeynikov | 2365f51 | 2007-07-14 14:06:15 +0000 | [diff] [blame] | 189 | const unsigned* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) |
| 190 | const { |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame] | 191 | static const unsigned CalleeSavedRegs[] = { 0 }; |
| 192 | return CalleeSavedRegs; |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 193 | } |
| 194 | |
Evan Cheng | b371f45 | 2007-02-19 21:49:54 +0000 | [diff] [blame] | 195 | BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const { |
| 196 | BitVector Reserved(getNumRegs()); |
| 197 | Reserved.set(SP::G2); |
| 198 | Reserved.set(SP::G3); |
| 199 | Reserved.set(SP::G4); |
| 200 | Reserved.set(SP::O6); |
| 201 | Reserved.set(SP::I6); |
| 202 | Reserved.set(SP::I7); |
| 203 | Reserved.set(SP::G0); |
| 204 | Reserved.set(SP::G5); |
| 205 | Reserved.set(SP::G6); |
| 206 | Reserved.set(SP::G7); |
| 207 | return Reserved; |
| 208 | } |
| 209 | |
| 210 | |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 211 | const TargetRegisterClass* const* |
Anton Korobeynikov | 2365f51 | 2007-07-14 14:06:15 +0000 | [diff] [blame] | 212 | SparcRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame] | 213 | static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 }; |
| 214 | return CalleeSavedRegClasses; |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 215 | } |
| 216 | |
Evan Cheng | dc77540 | 2007-01-23 00:57:47 +0000 | [diff] [blame] | 217 | bool SparcRegisterInfo::hasFP(const MachineFunction &MF) const { |
| 218 | return false; |
| 219 | } |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 220 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 221 | void SparcRegisterInfo:: |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 222 | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
| 223 | MachineBasicBlock::iterator I) const { |
Brian Gaeke | 85c0835 | 2004-10-10 19:57:21 +0000 | [diff] [blame] | 224 | MachineInstr &MI = *I; |
Chris Lattner | 43875e6 | 2005-12-19 02:51:12 +0000 | [diff] [blame] | 225 | int Size = MI.getOperand(0).getImmedValue(); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 226 | if (MI.getOpcode() == SP::ADJCALLSTACKDOWN) |
Chris Lattner | 43875e6 | 2005-12-19 02:51:12 +0000 | [diff] [blame] | 227 | Size = -Size; |
| 228 | if (Size) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 229 | BuildMI(MBB, I, TII.get(SP::ADDri), SP::O6).addReg(SP::O6).addImm(Size); |
Chris Lattner | 43875e6 | 2005-12-19 02:51:12 +0000 | [diff] [blame] | 230 | MBB.erase(I); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 231 | } |
| 232 | |
Evan Cheng | 5e6df46 | 2007-02-28 00:21:17 +0000 | [diff] [blame] | 233 | void SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, |
Evan Cheng | 97de913 | 2007-05-01 09:13:03 +0000 | [diff] [blame] | 234 | int SPAdj, RegScavenger *RS) const { |
| 235 | assert(SPAdj == 0 && "Unexpected"); |
| 236 | |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 237 | unsigned i = 0; |
| 238 | MachineInstr &MI = *II; |
| 239 | while (!MI.getOperand(i).isFrameIndex()) { |
| 240 | ++i; |
| 241 | assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); |
| 242 | } |
| 243 | |
| 244 | int FrameIndex = MI.getOperand(i).getFrameIndex(); |
| 245 | |
Brian Gaeke | 3a8ad62 | 2004-04-06 22:10:22 +0000 | [diff] [blame] | 246 | // Addressable stack objects are accessed using neg. offsets from %fp |
Chris Lattner | b8ce4c4 | 2004-08-14 22:57:22 +0000 | [diff] [blame] | 247 | MachineFunction &MF = *MI.getParent()->getParent(); |
Brian Gaeke | 3a8ad62 | 2004-04-06 22:10:22 +0000 | [diff] [blame] | 248 | int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + |
| 249 | MI.getOperand(i+1).getImmedValue(); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 250 | |
| 251 | // Replace frame index with a frame pointer reference. |
| 252 | if (Offset >= -4096 && Offset <= 4095) { |
| 253 | // If the offset is small enough to fit in the immediate field, directly |
| 254 | // encode it. |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 255 | MI.getOperand(i).ChangeToRegister(SP::I6, false); |
Chris Lattner | e53f4a0 | 2006-05-04 17:52:23 +0000 | [diff] [blame] | 256 | MI.getOperand(i+1).ChangeToImmediate(Offset); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 257 | } else { |
| 258 | // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to |
| 259 | // scavenge a register here instead of reserving G1 all of the time. |
| 260 | unsigned OffHi = (unsigned)Offset >> 10U; |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 261 | BuildMI(*MI.getParent(), II, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 262 | // Emit G1 = G1 + I6 |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 263 | BuildMI(*MI.getParent(), II, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1) |
| 264 | .addReg(SP::I6); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 265 | // Insert: G1+%lo(offset) into the user. |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 266 | MI.getOperand(i).ChangeToRegister(SP::G1, false); |
Chris Lattner | e53f4a0 | 2006-05-04 17:52:23 +0000 | [diff] [blame] | 267 | MI.getOperand(i+1).ChangeToImmediate(Offset & ((1 << 10)-1)); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 268 | } |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 269 | } |
| 270 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 271 | void SparcRegisterInfo:: |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 272 | processFunctionBeforeFrameFinalized(MachineFunction &MF) const {} |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 273 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 274 | void SparcRegisterInfo::emitPrologue(MachineFunction &MF) const { |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 275 | MachineBasicBlock &MBB = MF.front(); |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 276 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 277 | |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 278 | // Get the number of bytes to allocate from the FrameInfo |
Brian Gaeke | ef8e48a | 2004-04-13 18:28:37 +0000 | [diff] [blame] | 279 | int NumBytes = (int) MFI->getStackSize(); |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 280 | |
Brian Gaeke | 85c0835 | 2004-10-10 19:57:21 +0000 | [diff] [blame] | 281 | // Emit the correct save instruction based on the number of bytes in |
| 282 | // the frame. Minimum stack frame size according to V8 ABI is: |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 283 | // 16 words for register window spill |
| 284 | // 1 word for address of returned aggregate-value |
| 285 | // + 6 words for passing parameters on the stack |
| 286 | // ---------- |
| 287 | // 23 words * 4 bytes per word = 92 bytes |
| 288 | NumBytes += 92; |
Brian Gaeke | 6713d98 | 2004-06-17 22:34:48 +0000 | [diff] [blame] | 289 | // Round up to next doubleword boundary -- a double-word boundary |
| 290 | // is required by the ABI. |
| 291 | NumBytes = (NumBytes + 7) & ~7; |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 292 | NumBytes = -NumBytes; |
| 293 | |
| 294 | if (NumBytes >= -4096) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 295 | BuildMI(MBB, MBB.begin(), TII.get(SP::SAVEri), |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 296 | SP::O6).addImm(NumBytes).addReg(SP::O6); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 297 | } else { |
| 298 | MachineBasicBlock::iterator InsertPt = MBB.begin(); |
| 299 | // Emit this the hard way. This clobbers G1 which we always know is |
| 300 | // available here. |
| 301 | unsigned OffHi = (unsigned)NumBytes >> 10U; |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 302 | BuildMI(MBB, InsertPt, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 303 | // Emit G1 = G1 + I6 |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 304 | BuildMI(MBB, InsertPt, TII.get(SP::ORri), SP::G1) |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 305 | .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1)); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 306 | BuildMI(MBB, InsertPt, TII.get(SP::SAVErr), SP::O6) |
| 307 | .addReg(SP::O6).addReg(SP::G1); |
Chris Lattner | 85e42b4 | 2005-12-20 07:56:31 +0000 | [diff] [blame] | 308 | } |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 309 | } |
| 310 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 311 | void SparcRegisterInfo::emitEpilogue(MachineFunction &MF, |
| 312 | MachineBasicBlock &MBB) const { |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 313 | MachineBasicBlock::iterator MBBI = prior(MBB.end()); |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 314 | assert(MBBI->getOpcode() == SP::RETL && |
Brian Gaeke | d69b3c5 | 2004-03-06 05:31:21 +0000 | [diff] [blame] | 315 | "Can only put epilog before 'retl' instruction!"); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 316 | BuildMI(MBB, MBBI, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0) |
| 317 | .addReg(SP::G0); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 318 | } |
| 319 | |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 320 | unsigned SparcRegisterInfo::getRARegister() const { |
| 321 | assert(0 && "What is the return address register"); |
| 322 | return 0; |
| 323 | } |
| 324 | |
Jim Laskey | a997918 | 2006-03-28 13:48:33 +0000 | [diff] [blame] | 325 | unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const { |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 326 | assert(0 && "What is the frame register"); |
| 327 | return SP::G1; |
Jim Laskey | f1d78e8 | 2006-03-23 18:12:57 +0000 | [diff] [blame] | 328 | } |
| 329 | |
Jim Laskey | 62819f3 | 2007-02-21 22:54:50 +0000 | [diff] [blame] | 330 | unsigned SparcRegisterInfo::getEHExceptionRegister() const { |
| 331 | assert(0 && "What is the exception register"); |
| 332 | return 0; |
| 333 | } |
| 334 | |
| 335 | unsigned SparcRegisterInfo::getEHHandlerRegister() const { |
| 336 | assert(0 && "What is the exception handler register"); |
| 337 | return 0; |
| 338 | } |
| 339 | |
Dale Johannesen | b97aec6 | 2007-11-13 19:13:01 +0000 | [diff] [blame] | 340 | int SparcRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { |
Anton Korobeynikov | f191c80 | 2007-11-11 19:50:10 +0000 | [diff] [blame] | 341 | assert(0 && "What is the dwarf register number"); |
| 342 | return -1; |
| 343 | } |
| 344 | |
Chris Lattner | 7c90f73 | 2006-02-05 05:50:24 +0000 | [diff] [blame] | 345 | #include "SparcGenRegisterInfo.inc" |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 346 | |